From f659bf38610310ff063e9bdbad378688cf61850d Mon Sep 17 00:00:00 2001 From: Zoran Kokeza Date: Sat, 6 Aug 2022 11:45:30 +0200 Subject: [PATCH 01/15] fix: move map credits to map column so chart don't hide it --- CHANGES.md | 2 ++ lib/ReactViews/StandardUserInterface/MapColumn.jsx | 11 +++++++++++ .../StandardUserInterface/StandardUserInterface.tsx | 8 +------- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index bd44995d8c8..2ee195934b9 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -23,6 +23,8 @@ Change Log * Fix `SearchBoxAndResults` Trans values * Fix `generateCatalogIndex` for nested references * Fix `SearchBox` handling of `searchWithDebounce` when `debounceDuration` prop changes. It now fushes instead of cancels. +* Move map credits to map column so it don't get hidden by chart panel +* [The next improvement] #### release 8.2.10 - 2022-08-02 diff --git a/lib/ReactViews/StandardUserInterface/MapColumn.jsx b/lib/ReactViews/StandardUserInterface/MapColumn.jsx index f1eb25f7433..037a2b31bbe 100644 --- a/lib/ReactViews/StandardUserInterface/MapColumn.jsx +++ b/lib/ReactViews/StandardUserInterface/MapColumn.jsx @@ -6,6 +6,7 @@ import React from "react"; import { withTranslation } from "react-i18next"; import FeatureDetection from "terriajs-cesium/Source/Core/FeatureDetection"; import BottomDock from "../BottomDock/BottomDock"; +import { MapCredits } from "../Credits"; import Loader from "../Loader"; import BottomLeftBar from "../Map/BottomLeftBar/BottomLeftBar"; import DistanceLegend from "../Map/Legend/DistanceLegend"; @@ -117,6 +118,16 @@ const MapColumn = observer( /> +
= observer( allBaseMaps={allBaseMaps} animationDuration={animationDuration} /> -
From 642b1d5b4a6371bbe00b18d3ae8227da49f0e0aa Mon Sep 17 00:00:00 2001 From: Zoran Kokeza Date: Mon, 8 Aug 2022 10:55:53 +0200 Subject: [PATCH 02/15] feat: tsify map column and reorganize some of the components --- lib/Models/Terria.ts | 2 +- lib/ReactViewModels/MouseCoords.ts | 10 +- lib/ReactViews/BottomDock/BottomDock.tsx | 6 +- .../ContextProviders.tsx | 2 +- .../ViewStateContext.tsx | 0 lib/ReactViews/Context/index.ts | 2 + lib/ReactViews/Credits/index.ts | 2 - lib/ReactViews/Custom/ExternalLink.tsx | 2 +- lib/ReactViews/Disclaimer.jsx | 2 +- lib/ReactViews/DragDropFile.tsx | 5 +- lib/ReactViews/DragDropNotification.jsx | 2 +- .../ExplorerWindow/ExplorerWindow.tsx | 2 +- .../FeatureInfo/FeatureInfoPanel.jsx | 2 +- lib/ReactViews/Feedback/FeedbackForm.tsx | 5 +- .../HelpScreens/SatelliteHelpPrompt.jsx | 2 +- lib/ReactViews/Map/BottomBar/BottomBar.tsx | 31 +++ .../{ => Map/BottomBar}/Credits/Credit.tsx | 2 +- .../BottomBar}/Credits/Credit.type.ts | 0 .../{ => Map/BottomBar}/Credits/Credits.tsx | 0 .../BottomBar}/Credits/CreditsContainer.tsx | 12 +- .../DataAttribution/DataAttributionModal.tsx | 15 +- .../BottomBar/Credits}/MapCreditLogo.tsx | 6 +- .../BottomBar/Credits}/MapCredits.tsx | 14 +- .../{ => Map/BottomBar}/Credits/Spacer.tsx | 0 .../BottomBar}/Credits/TerriaLogo.tsx | 4 +- lib/ReactViews/Map/BottomBar/Credits/index.ts | 2 + .../Map/BottomBar/DistanceLegend.tsx | 243 ++++++++++++++++++ lib/ReactViews/Map/BottomBar/LocationBar.tsx | 88 +++++++ lib/ReactViews/Map/BottomBar/index.ts | 1 + .../Map/BottomLeftBar/BottomLeftBar.tsx | 34 ++- .../Map/HelpButton/help-button.scss | 4 - lib/ReactViews/Map/Legend/DistanceLegend.jsx | 233 ----------------- lib/ReactViews/Map/Legend/LocationBar.jsx | 82 ------ lib/ReactViews/Map/Legend/legend.scss | 75 ------ lib/ReactViews/Map/Legend/legend.scss.d.ts | 15 -- lib/ReactViews/Map/MapColumn.tsx | 136 ++++++++++ .../CollapsedNavigation.tsx} | 24 +- .../Items/AugmentedVirtualityTool.tsx | 0 .../Items/CatalogShortcut.jsx | 0 .../Items/CloseToolButton.tsx | 19 +- .../Items/Compass}/Compass.tsx | 50 ++-- .../Items/Compass}/GyroscopeGuidance.jsx | 18 +- .../Map/MapNavigation/Items/Compass/index.ts | 1 + .../Items/MapNavigationItem.tsx | 4 +- .../Items/MeasureTool.ts | 2 +- .../Items/MyLocation.ts | 4 +- .../Items/ToggleSplitterTool.ts | 0 .../Items/ToolButton.tsx | 0 .../Items/ZoomControl.tsx | 7 +- .../Map/MapNavigation/Items/index.ts | 14 + .../MapNavigation.tsx | 34 +-- .../filterViewerAndScreenSize.ts | 25 ++ lib/ReactViews/Map/MapNavigation/index.ts | 2 + .../registerMapNavigations.tsx | 20 +- .../{ => MenuBar}/HelpButton/HelpButton.tsx | 8 +- .../Map/MenuBar/HelpButton/help-button.scss | 4 + .../HelpButton/help-button.scss.d.ts | 0 lib/ReactViews/Map/{ => MenuBar}/MenuBar.jsx | 11 +- .../{ => MenuBar}/StoryButton/StoryButton.tsx | 14 +- .../Map/MenuBar/StoryButton/story-button.scss | 13 + .../StoryButton/story-button.scss.d.ts | 0 .../Map/{ => MenuBar}/menu-bar.scss | 12 +- .../Map/{ => MenuBar}/menu-bar.scss.d.ts | 0 .../Map/Navigation/FullScreenButton.jsx | 60 ----- .../Map/Panels/HelpPanel/HelpPanel.jsx | 2 +- .../Map/Panels/HelpPanel/HelpPanelItem.jsx | 2 +- .../Map/Panels/LangPanel/LangPanel.tsx | 2 +- .../Map/Panels/SharePanel/Print/PrintView.tsx | 16 +- lib/ReactViews/Map/ProgressBar.jsx | 105 -------- lib/ReactViews/Map/ProgressBar.tsx | 90 +++++++ lib/ReactViews/Map/Splitter.jsx | 230 ----------------- .../Map/StoryButton/story-button.scss | 13 - lib/ReactViews/Map/TerriaViewerWrapper.jsx | 57 ---- .../TerriaViewerWrapper/Splitter/Splitter.tsx | 102 ++++++++ .../TerriaViewerWrapper/Splitter/dragHook.ts | 166 ++++++++++++ .../TerriaViewerWrapper.tsx | 84 ++++++ .../Map/TerriaViewerWrapper/index.ts | 1 + .../{StandardUserInterface => Map}/Toast.tsx | 0 lib/ReactViews/Map/experimental-features.scss | 22 -- .../Map/experimental-features.scss.d.ts | 9 - lib/ReactViews/Map/progress-bar.scss | 31 --- lib/ReactViews/Map/progress-bar.scss.d.ts | 12 - lib/ReactViews/Map/splitter.scss | 42 --- lib/ReactViews/Map/splitter.scss.d.ts | 10 - lib/ReactViews/Map/terria-viewer-wrapper.scss | 57 ---- .../Map/terria-viewer-wrapper.scss.d.ts | 10 - lib/ReactViews/Mobile/MobileHeader.jsx | 4 +- lib/ReactViews/Mobile/MobileMenu.jsx | 1 - .../Notification/MapInteractionWindow.tsx | 2 +- lib/ReactViews/Notification/Notification.tsx | 2 +- lib/ReactViews/SidePanel/Branding.tsx | 2 +- lib/ReactViews/SidePanel/FullScreenButton.jsx | 2 +- lib/ReactViews/SidePanel/SidePanel.tsx | 6 +- .../ExperimentalFeatures.tsx | 4 +- .../GlobalTerriaStyles.ts | 15 ++ .../StandardUserInterface/MapColumn.jsx | 219 ---------------- .../SidePanelContainer.tsx | 2 +- .../StandardUserInterface.tsx | 21 +- .../TrainerBar/TrainerBar.tsx | 5 +- .../WorkflowPanelContainer.tsx | 4 +- .../customizable}/MenuButton.jsx | 2 +- .../customizable/MenuItem.jsx | 2 +- .../customizable}/menu-button.scss | 4 +- .../customizable}/menu-button.scss.d.ts | 0 lib/ReactViews/StandardUserInterface/index.ts | 5 + .../StandardUserInterface/map-column.scss | 99 ------- .../map-column.scss.d.ts | 29 --- lib/ReactViews/Story/StoryBuilder.tsx | 5 +- .../Story/StoryPanel/StoryPanel.tsx | 7 +- lib/ReactViews/Tools/DiffTool/DiffTool.tsx | 3 +- .../Tools/PedestrianMode/PedestrianMode.tsx | 2 +- lib/ReactViews/Tools/Tool.tsx | 2 +- lib/ReactViews/Tour/TourPortal.jsx | 2 +- .../WelcomeMessage/WelcomeMessage.jsx | 2 +- .../{Map/Panels => Workbench}/TerrainSide.tsx | 14 +- .../Workbench/WorkbenchSplitScreen.tsx | 2 +- .../Workflow/SelectableDimensionWorkflow.tsx | 2 +- lib/Styled/Text.tsx | 9 +- .../terriajs-cesium-extra/index.d.ts | 1 + test/Map/StyledHtmlSpec.tsx | 2 +- test/ReactViews/ClipboardSpec.tsx | 2 +- .../DimensionSelectorSectionSpec.tsx | 2 +- test/ReactViews/Generic/PromptSpec.tsx | 2 +- .../Map/Navigation/Compass/CompassSpec.tsx | 6 +- .../Compass}/GyroscopeGuidanceSpec.tsx | 8 +- .../Map/Panels/HelpPanel/VideoGuideSpec.tsx | 2 +- test/ReactViews/MeasureToolSpec.jsx | 2 +- test/ReactViews/Preview/DescriptionSpec.tsx | 2 +- test/ReactViews/Search/BreadcrumbsSpec.tsx | 2 +- .../Search/SearchBoxAndResultsSpec.tsx | 2 +- test/ReactViews/Search/SearchBoxSpec.tsx | 2 +- test/ReactViews/ShortReportSpec.tsx | 2 +- .../TrainerBar/TrainerBarSpec.tsx | 2 +- .../TrainerBar/test-help-content.js | 0 test/ReactViews/WarningBoxSpec.tsx | 2 +- test/ReactViews/withContext.tsx | 4 +- 136 files changed, 1261 insertions(+), 1716 deletions(-) rename lib/ReactViews/{StandardUserInterface => Context}/ContextProviders.tsx (91%) rename lib/ReactViews/{StandardUserInterface => Context}/ViewStateContext.tsx (100%) create mode 100644 lib/ReactViews/Context/index.ts delete mode 100644 lib/ReactViews/Credits/index.ts create mode 100644 lib/ReactViews/Map/BottomBar/BottomBar.tsx rename lib/ReactViews/{ => Map/BottomBar}/Credits/Credit.tsx (89%) rename lib/ReactViews/{ => Map/BottomBar}/Credits/Credit.type.ts (100%) rename lib/ReactViews/{ => Map/BottomBar}/Credits/Credits.tsx (100%) rename lib/ReactViews/{ => Map/BottomBar}/Credits/CreditsContainer.tsx (62%) rename lib/ReactViews/{ => Map/BottomBar}/Credits/DataAttribution/DataAttributionModal.tsx (86%) rename lib/ReactViews/{Credits/MapCredits => Map/BottomBar/Credits}/MapCreditLogo.tsx (75%) rename lib/ReactViews/{Credits/MapCredits => Map/BottomBar/Credits}/MapCredits.tsx (84%) rename lib/ReactViews/{ => Map/BottomBar}/Credits/Spacer.tsx (100%) rename lib/ReactViews/{ => Map/BottomBar}/Credits/TerriaLogo.tsx (71%) create mode 100644 lib/ReactViews/Map/BottomBar/Credits/index.ts create mode 100644 lib/ReactViews/Map/BottomBar/DistanceLegend.tsx create mode 100644 lib/ReactViews/Map/BottomBar/LocationBar.tsx create mode 100644 lib/ReactViews/Map/BottomBar/index.ts delete mode 100644 lib/ReactViews/Map/HelpButton/help-button.scss delete mode 100644 lib/ReactViews/Map/Legend/DistanceLegend.jsx delete mode 100644 lib/ReactViews/Map/Legend/LocationBar.jsx delete mode 100644 lib/ReactViews/Map/Legend/legend.scss delete mode 100644 lib/ReactViews/Map/Legend/legend.scss.d.ts create mode 100644 lib/ReactViews/Map/MapColumn.tsx rename lib/ReactViews/Map/{Navigation/Items/OverflowNavigationItem.tsx => MapNavigation/CollapsedNavigation.tsx} (84%) rename lib/ReactViews/Map/{Navigation => MapNavigation}/Items/AugmentedVirtualityTool.tsx (100%) rename lib/ReactViews/Map/{Navigation => MapNavigation}/Items/CatalogShortcut.jsx (100%) rename lib/ReactViews/Map/{Navigation => MapNavigation}/Items/CloseToolButton.tsx (65%) rename lib/ReactViews/Map/{Navigation/Items => MapNavigation/Items/Compass}/Compass.tsx (94%) rename lib/ReactViews/{GyroscopeGuidance => Map/MapNavigation/Items/Compass}/GyroscopeGuidance.jsx (91%) create mode 100644 lib/ReactViews/Map/MapNavigation/Items/Compass/index.ts rename lib/ReactViews/Map/{Navigation => MapNavigation}/Items/MapNavigationItem.tsx (94%) rename lib/ReactViews/Map/{Navigation => MapNavigation}/Items/MeasureTool.ts (99%) rename lib/ReactViews/Map/{Navigation => MapNavigation}/Items/MyLocation.ts (98%) rename lib/ReactViews/Map/{Navigation => MapNavigation}/Items/ToggleSplitterTool.ts (100%) rename lib/ReactViews/Map/{Navigation => MapNavigation}/Items/ToolButton.tsx (100%) rename lib/ReactViews/Map/{Navigation => MapNavigation}/Items/ZoomControl.tsx (97%) create mode 100644 lib/ReactViews/Map/MapNavigation/Items/index.ts rename lib/ReactViews/Map/{Navigation => MapNavigation}/MapNavigation.tsx (90%) create mode 100644 lib/ReactViews/Map/MapNavigation/filterViewerAndScreenSize.ts create mode 100644 lib/ReactViews/Map/MapNavigation/index.ts rename lib/ReactViews/Map/{Navigation => MapNavigation}/registerMapNavigations.tsx (92%) rename lib/ReactViews/Map/{ => MenuBar}/HelpButton/HelpButton.tsx (86%) create mode 100644 lib/ReactViews/Map/MenuBar/HelpButton/help-button.scss rename lib/ReactViews/Map/{ => MenuBar}/HelpButton/help-button.scss.d.ts (100%) rename lib/ReactViews/Map/{ => MenuBar}/MenuBar.jsx (91%) rename lib/ReactViews/Map/{ => MenuBar}/StoryButton/StoryButton.tsx (88%) create mode 100644 lib/ReactViews/Map/MenuBar/StoryButton/story-button.scss rename lib/ReactViews/Map/{ => MenuBar}/StoryButton/story-button.scss.d.ts (100%) rename lib/ReactViews/Map/{ => MenuBar}/menu-bar.scss (83%) rename lib/ReactViews/Map/{ => MenuBar}/menu-bar.scss.d.ts (100%) delete mode 100644 lib/ReactViews/Map/Navigation/FullScreenButton.jsx delete mode 100644 lib/ReactViews/Map/ProgressBar.jsx create mode 100644 lib/ReactViews/Map/ProgressBar.tsx delete mode 100644 lib/ReactViews/Map/Splitter.jsx delete mode 100644 lib/ReactViews/Map/StoryButton/story-button.scss delete mode 100644 lib/ReactViews/Map/TerriaViewerWrapper.jsx create mode 100644 lib/ReactViews/Map/TerriaViewerWrapper/Splitter/Splitter.tsx create mode 100644 lib/ReactViews/Map/TerriaViewerWrapper/Splitter/dragHook.ts create mode 100644 lib/ReactViews/Map/TerriaViewerWrapper/TerriaViewerWrapper.tsx create mode 100644 lib/ReactViews/Map/TerriaViewerWrapper/index.ts rename lib/ReactViews/{StandardUserInterface => Map}/Toast.tsx (100%) delete mode 100644 lib/ReactViews/Map/experimental-features.scss delete mode 100644 lib/ReactViews/Map/experimental-features.scss.d.ts delete mode 100644 lib/ReactViews/Map/progress-bar.scss delete mode 100644 lib/ReactViews/Map/progress-bar.scss.d.ts delete mode 100644 lib/ReactViews/Map/splitter.scss delete mode 100644 lib/ReactViews/Map/splitter.scss.d.ts delete mode 100644 lib/ReactViews/Map/terria-viewer-wrapper.scss delete mode 100644 lib/ReactViews/Map/terria-viewer-wrapper.scss.d.ts rename lib/ReactViews/{Map => StandardUserInterface}/ExperimentalFeatures.tsx (91%) delete mode 100644 lib/ReactViews/StandardUserInterface/MapColumn.jsx rename lib/ReactViews/{Map => StandardUserInterface}/TrainerBar/TrainerBar.tsx (99%) rename lib/ReactViews/{Map => StandardUserInterface/customizable}/MenuButton.jsx (95%) rename lib/ReactViews/{Map => StandardUserInterface/customizable}/menu-button.scss (74%) rename lib/ReactViews/{Map => StandardUserInterface/customizable}/menu-button.scss.d.ts (100%) create mode 100644 lib/ReactViews/StandardUserInterface/index.ts delete mode 100644 lib/ReactViews/StandardUserInterface/map-column.scss delete mode 100644 lib/ReactViews/StandardUserInterface/map-column.scss.d.ts rename lib/ReactViews/{Map/Panels => Workbench}/TerrainSide.tsx (92%) rename test/ReactViews/{GyroscopeGuidance => Map/Navigation/Compass}/GyroscopeGuidanceSpec.tsx (74%) rename test/ReactViews/{Map => StandardUserInterface}/TrainerBar/TrainerBarSpec.tsx (96%) rename test/ReactViews/{Map => StandardUserInterface}/TrainerBar/test-help-content.js (100%) diff --git a/lib/Models/Terria.ts b/lib/Models/Terria.ts index 388e7609c60..abfaf1c15dd 100644 --- a/lib/Models/Terria.ts +++ b/lib/Models/Terria.ts @@ -58,7 +58,7 @@ import TimeVarying from "../ModelMixins/TimeVarying"; import { HelpContentItem } from "../ReactViewModels/defaultHelpContent"; import { defaultTerms, Term } from "../ReactViewModels/defaultTerms"; import NotificationState from "../ReactViewModels/NotificationState"; -import { ICredit } from "../ReactViews/Credits"; +import { ICredit } from "../ReactViews/Map/BottomBar/Credits"; import { SHARE_VERSION } from "../ReactViews/Map/Panels/SharePanel/BuildShareLink"; import { shareConvertNotification } from "../ReactViews/Notification/shareConvertNotification"; import MappableTraits from "../Traits/TraitsClasses/MappableTraits"; diff --git a/lib/ReactViewModels/MouseCoords.ts b/lib/ReactViewModels/MouseCoords.ts index c018c17cc0c..7c2caf39368 100644 --- a/lib/ReactViewModels/MouseCoords.ts +++ b/lib/ReactViewModels/MouseCoords.ts @@ -38,11 +38,11 @@ export default class MouseCoords { tileRequestInFlight?: unknown; @observable elevation?: string; - @observable utmZone?: unknown; + @observable utmZone?: string; @observable latitude?: string; @observable longitude?: string; - @observable north?: unknown; - @observable east?: unknown; + @observable north?: string; + @observable east?: string; @observable cartographic?: Cartographic; @observable useProjection = false; @@ -64,11 +64,12 @@ export default class MouseCoords { ); } - @action + @action.bound toggleUseProjection() { this.useProjection = !this.useProjection; } + @action updateCoordinatesFromCesium(terria: Terria, position: Cartesian2) { if (!terria.cesium) { return; @@ -156,6 +157,7 @@ export default class MouseCoords { } } + @action updateCoordinatesFromLeaflet(terria: Terria, mouseMoveEvent: MouseEvent) { if (!terria.leaflet) { return; diff --git a/lib/ReactViews/BottomDock/BottomDock.tsx b/lib/ReactViews/BottomDock/BottomDock.tsx index b5ce4e93357..fe83d947f90 100644 --- a/lib/ReactViews/BottomDock/BottomDock.tsx +++ b/lib/ReactViews/BottomDock/BottomDock.tsx @@ -10,13 +10,13 @@ import Styles from "./bottom-dock.scss"; import ChartDisclaimer from "./ChartDisclaimer"; import Timeline from "./Timeline/Timeline"; -interface PropsType extends MeasureElementProps { +interface PropsType { terria: Terria; viewState: ViewState; } @observer -class BottomDock extends React.Component { +class BottomDock extends React.Component { refToMeasure: HTMLDivElement | null = null; handleClick() { @@ -25,7 +25,7 @@ class BottomDock extends React.Component { }); } - componentDidUpdate(prevProps: PropsType) { + componentDidUpdate(prevProps: PropsType & MeasureElementProps) { if ( prevProps.heightFromMeasureElementHOC !== this.props.heightFromMeasureElementHOC diff --git a/lib/ReactViews/StandardUserInterface/ContextProviders.tsx b/lib/ReactViews/Context/ContextProviders.tsx similarity index 91% rename from lib/ReactViews/StandardUserInterface/ContextProviders.tsx rename to lib/ReactViews/Context/ContextProviders.tsx index 44bc042c5e6..06854c0c0de 100644 --- a/lib/ReactViews/StandardUserInterface/ContextProviders.tsx +++ b/lib/ReactViews/Context/ContextProviders.tsx @@ -3,7 +3,7 @@ import { DefaultTheme, ThemeProvider } from "styled-components"; import ViewState from "../../ReactViewModels/ViewState"; import { ViewStateProvider } from "./ViewStateContext"; -export default (props: { +export const ContextProviders = (props: { viewState: ViewState; theme: DefaultTheme | ((theme: DefaultTheme) => DefaultTheme); children: React.ReactNode[]; diff --git a/lib/ReactViews/StandardUserInterface/ViewStateContext.tsx b/lib/ReactViews/Context/ViewStateContext.tsx similarity index 100% rename from lib/ReactViews/StandardUserInterface/ViewStateContext.tsx rename to lib/ReactViews/Context/ViewStateContext.tsx diff --git a/lib/ReactViews/Context/index.ts b/lib/ReactViews/Context/index.ts new file mode 100644 index 00000000000..fba95c1445c --- /dev/null +++ b/lib/ReactViews/Context/index.ts @@ -0,0 +1,2 @@ +export * from "./ViewStateContext"; +export * from "./ContextProviders"; diff --git a/lib/ReactViews/Credits/index.ts b/lib/ReactViews/Credits/index.ts deleted file mode 100644 index c64853d9cd8..00000000000 --- a/lib/ReactViews/Credits/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { ICredit } from "./Credit.type"; -export { MapCredits } from "./MapCredits/MapCredits"; diff --git a/lib/ReactViews/Custom/ExternalLink.tsx b/lib/ReactViews/Custom/ExternalLink.tsx index a82e7964c3e..5d6669b974e 100644 --- a/lib/ReactViews/Custom/ExternalLink.tsx +++ b/lib/ReactViews/Custom/ExternalLink.tsx @@ -1,7 +1,7 @@ import { AnchorHTMLAttributes, default as React } from "react"; import { useTranslation } from "react-i18next"; import styled from "styled-components"; -import { useViewState } from "../StandardUserInterface/ViewStateContext"; +import { useViewState } from "../Context"; const Icon = require("../../Styled/Icon").default; const { StyledIcon } = require("../../Styled/Icon"); diff --git a/lib/ReactViews/Disclaimer.jsx b/lib/ReactViews/Disclaimer.jsx index 7ee23f377c6..6cabf1c1326 100644 --- a/lib/ReactViews/Disclaimer.jsx +++ b/lib/ReactViews/Disclaimer.jsx @@ -12,7 +12,7 @@ import Button from "../Styled/Button"; import Spacing from "../Styled/Spacing"; import Text from "../Styled/Text"; import parseCustomMarkdownToReact from "./Custom/parseCustomMarkdownToReact"; -import { withViewState } from "./StandardUserInterface/ViewStateContext"; +import { withViewState } from "./Context"; import FadeIn from "./Transitions/FadeIn/FadeIn"; const TopElementBox = styled(Box)` diff --git a/lib/ReactViews/DragDropFile.tsx b/lib/ReactViews/DragDropFile.tsx index e0162f9591f..777df0f0515 100644 --- a/lib/ReactViews/DragDropFile.tsx +++ b/lib/ReactViews/DragDropFile.tsx @@ -14,10 +14,7 @@ import MappableMixin from "../ModelMixins/MappableMixin"; import addUserFiles from "../Models/Catalog/addUserFiles"; import { BaseModel } from "../Models/Definition/Model"; import Styles from "./drag-drop-file.scss"; -import { - WithViewState, - withViewState -} from "./StandardUserInterface/ViewStateContext"; +import { WithViewState, withViewState } from "./Context"; interface PropsType extends WithTranslation, WithViewState {} diff --git a/lib/ReactViews/DragDropNotification.jsx b/lib/ReactViews/DragDropNotification.jsx index fec17f6ab94..63bf30c8c7d 100644 --- a/lib/ReactViews/DragDropNotification.jsx +++ b/lib/ReactViews/DragDropNotification.jsx @@ -6,7 +6,7 @@ import PropTypes from "prop-types"; import React from "react"; import Icon from "../Styled/Icon"; import Styles from "./drag-drop-notification.scss"; -import { withViewState } from "./StandardUserInterface/ViewStateContext"; +import { withViewState } from "./Context"; @observer class DragDropNotification extends React.Component { diff --git a/lib/ReactViews/ExplorerWindow/ExplorerWindow.tsx b/lib/ReactViews/ExplorerWindow/ExplorerWindow.tsx index 91dac320a8b..5ed52578fe7 100644 --- a/lib/ReactViews/ExplorerWindow/ExplorerWindow.tsx +++ b/lib/ReactViews/ExplorerWindow/ExplorerWindow.tsx @@ -2,7 +2,7 @@ import { action } from "mobx"; import { observer } from "mobx-react"; import React from "react"; import ViewState from "../../ReactViewModels/ViewState"; -import { useViewState } from "../StandardUserInterface/ViewStateContext"; +import { useViewState } from "../Context"; import ModalPopup from "./ModalPopup"; import Tabs from "./Tabs"; diff --git a/lib/ReactViews/FeatureInfo/FeatureInfoPanel.jsx b/lib/ReactViews/FeatureInfo/FeatureInfoPanel.jsx index 8a3c3c92219..1ecd8cd561c 100644 --- a/lib/ReactViews/FeatureInfo/FeatureInfoPanel.jsx +++ b/lib/ReactViews/FeatureInfo/FeatureInfoPanel.jsx @@ -22,7 +22,7 @@ import { import Icon from "../../Styled/Icon"; import DragWrapper from "../DragWrapper"; import Loader from "../Loader"; -import { withViewState } from "../StandardUserInterface/ViewStateContext"; +import { withViewState } from "../Context"; import Styles from "./feature-info-panel.scss"; import FeatureInfoCatalogItem from "./FeatureInfoCatalogItem"; diff --git a/lib/ReactViews/Feedback/FeedbackForm.tsx b/lib/ReactViews/Feedback/FeedbackForm.tsx index 564bcbba485..4524f8eb34b 100644 --- a/lib/ReactViews/Feedback/FeedbackForm.tsx +++ b/lib/ReactViews/Feedback/FeedbackForm.tsx @@ -16,10 +16,7 @@ import Text from "../../Styled/Text"; import parseCustomMarkdownToReact, { parseCustomMarkdownToReactWithOptions } from "../Custom/parseCustomMarkdownToReact"; -import { - WithViewState, - withViewState -} from "../StandardUserInterface/ViewStateContext"; +import { WithViewState, withViewState } from "../Context"; import { applyTranslationIfExists } from "./../../Language/languageHelpers"; interface IProps extends WithTranslation, WithViewState { diff --git a/lib/ReactViews/HelpScreens/SatelliteHelpPrompt.jsx b/lib/ReactViews/HelpScreens/SatelliteHelpPrompt.jsx index 57aa0fbfcd2..5bf038c3956 100644 --- a/lib/ReactViews/HelpScreens/SatelliteHelpPrompt.jsx +++ b/lib/ReactViews/HelpScreens/SatelliteHelpPrompt.jsx @@ -1,7 +1,7 @@ import { observer } from "mobx-react"; import React from "react"; import { useTranslation } from "react-i18next"; -import { useViewState } from "../StandardUserInterface/ViewStateContext"; +import { useViewState } from "../Context"; import HelpPrompt from "./HelpPrompt"; export const SATELLITE_HELP_PROMPT_KEY = "satelliteGuidance"; diff --git a/lib/ReactViews/Map/BottomBar/BottomBar.tsx b/lib/ReactViews/Map/BottomBar/BottomBar.tsx new file mode 100644 index 00000000000..5e04dc4b151 --- /dev/null +++ b/lib/ReactViews/Map/BottomBar/BottomBar.tsx @@ -0,0 +1,31 @@ +import React, { VFC } from "react"; +import Box from "../../../Styled/Box"; +import { MapCredits } from "./Credits"; +import { useViewState } from "../../Context"; +import { DistanceLegend } from "./DistanceLegend"; +import { LocationBar } from "./LocationBar"; + +export const BottomBar: VFC = () => { + const viewState = useViewState(); + return ( + + + + + + + + ); +}; diff --git a/lib/ReactViews/Credits/Credit.tsx b/lib/ReactViews/Map/BottomBar/Credits/Credit.tsx similarity index 89% rename from lib/ReactViews/Credits/Credit.tsx rename to lib/ReactViews/Map/BottomBar/Credits/Credit.tsx index 5901407ea9c..751297ff0f7 100644 --- a/lib/ReactViews/Credits/Credit.tsx +++ b/lib/ReactViews/Map/BottomBar/Credits/Credit.tsx @@ -1,6 +1,6 @@ import React, { FC } from "react"; import { useTranslation } from "react-i18next"; -import { ExternalLinkIcon } from "../Custom/ExternalLink"; +import { ExternalLinkIcon } from "../../../Custom/ExternalLink"; import { ICredit } from "./Credit.type"; import { Spacer } from "./Spacer"; diff --git a/lib/ReactViews/Credits/Credit.type.ts b/lib/ReactViews/Map/BottomBar/Credits/Credit.type.ts similarity index 100% rename from lib/ReactViews/Credits/Credit.type.ts rename to lib/ReactViews/Map/BottomBar/Credits/Credit.type.ts diff --git a/lib/ReactViews/Credits/Credits.tsx b/lib/ReactViews/Map/BottomBar/Credits/Credits.tsx similarity index 100% rename from lib/ReactViews/Credits/Credits.tsx rename to lib/ReactViews/Map/BottomBar/Credits/Credits.tsx diff --git a/lib/ReactViews/Credits/CreditsContainer.tsx b/lib/ReactViews/Map/BottomBar/Credits/CreditsContainer.tsx similarity index 62% rename from lib/ReactViews/Credits/CreditsContainer.tsx rename to lib/ReactViews/Map/BottomBar/Credits/CreditsContainer.tsx index 5d06fef8d7b..06c7d15afa7 100644 --- a/lib/ReactViews/Credits/CreditsContainer.tsx +++ b/lib/ReactViews/Map/BottomBar/Credits/CreditsContainer.tsx @@ -1,19 +1,12 @@ import styled from "styled-components"; -import Box from "../../Styled/Box"; +import Box from "../../../../Styled/Box"; export const CreditsContainer = styled(Box).attrs(() => ({ - fullWidth: true, styledHeight: "30px", styledMaxHeight: "30px", verticalCenter: true, - gap: true, - position: "absolute" + gap: true }))` - z-index: 0; - bottom: 0; - background: linear-gradient(180deg, #000000 0%, #000000 100%); - font-size: 0.7rem; - opacity: 0.75; a { text-decoration: underline; cursor: pointer; @@ -21,7 +14,6 @@ export const CreditsContainer = styled(Box).attrs(() => ({ display: flex; align-items: center; } - img { height: 24px; } diff --git a/lib/ReactViews/Credits/DataAttribution/DataAttributionModal.tsx b/lib/ReactViews/Map/BottomBar/Credits/DataAttribution/DataAttributionModal.tsx similarity index 86% rename from lib/ReactViews/Credits/DataAttribution/DataAttributionModal.tsx rename to lib/ReactViews/Map/BottomBar/Credits/DataAttribution/DataAttributionModal.tsx index 192a77f4956..a93d967a0e3 100644 --- a/lib/ReactViews/Credits/DataAttribution/DataAttributionModal.tsx +++ b/lib/ReactViews/Map/BottomBar/Credits/DataAttribution/DataAttributionModal.tsx @@ -3,13 +3,13 @@ import React, { FC } from "react"; import ReactDOM from "react-dom"; import { useTranslation } from "react-i18next"; import styled from "styled-components"; -import Box from "../../../Styled/Box"; -import { Li } from "../../../Styled/List"; -import Spacing from "../../../Styled/Spacing"; -import Text from "../../../Styled/Text"; -import parseCustomHtmlToReact from "../../Custom/parseCustomHtmlToReact"; -import CloseButton from "../../Generic/CloseButton"; -import { PrefaceBox } from "../../Generic/PrefaceBox"; +import Box from "../../../../../Styled/Box"; +import { Li } from "../../../../../Styled/List"; +import Spacing from "../../../../../Styled/Spacing"; +import Text from "../../../../../Styled/Text"; +import parseCustomHtmlToReact from "../../../../Custom/parseCustomHtmlToReact"; +import CloseButton from "../../../../Generic/CloseButton"; +import { PrefaceBox } from "../../../../Generic/PrefaceBox"; interface IDataAttributionModalProps { closeModal: () => void; @@ -20,7 +20,6 @@ const AttributionText = styled(Text).attrs(() => ({ medium: true }))` a { color: ${props => props.theme.textDark}; text-decoration: underline; - img { height: 19px; vertical-align: middle; diff --git a/lib/ReactViews/Credits/MapCredits/MapCreditLogo.tsx b/lib/ReactViews/Map/BottomBar/Credits/MapCreditLogo.tsx similarity index 75% rename from lib/ReactViews/Credits/MapCredits/MapCreditLogo.tsx rename to lib/ReactViews/Map/BottomBar/Credits/MapCreditLogo.tsx index 9ba2b6be382..7f0cffb0b18 100644 --- a/lib/ReactViews/Credits/MapCredits/MapCreditLogo.tsx +++ b/lib/ReactViews/Map/BottomBar/Credits/MapCreditLogo.tsx @@ -1,8 +1,8 @@ import React, { FC } from "react"; import CreditDisplay from "terriajs-cesium/Source/Scene/CreditDisplay"; -import GlobeOrMap from "../../../Models/GlobeOrMap"; -import Leaflet from "../../../Models/Leaflet"; -import parseCustomHtmlToReact from "../../Custom/parseCustomHtmlToReact"; +import GlobeOrMap from "../../../../Models/GlobeOrMap"; +import Leaflet from "../../../../Models/Leaflet"; +import parseCustomHtmlToReact from "../../../Custom/parseCustomHtmlToReact"; interface IMapCreditLogoProps { currentViewer: GlobeOrMap; diff --git a/lib/ReactViews/Credits/MapCredits/MapCredits.tsx b/lib/ReactViews/Map/BottomBar/Credits/MapCredits.tsx similarity index 84% rename from lib/ReactViews/Credits/MapCredits/MapCredits.tsx rename to lib/ReactViews/Map/BottomBar/Credits/MapCredits.tsx index 404abdeeb8b..05a8a30a118 100644 --- a/lib/ReactViews/Credits/MapCredits/MapCredits.tsx +++ b/lib/ReactViews/Map/BottomBar/Credits/MapCredits.tsx @@ -2,13 +2,13 @@ import { reaction } from "mobx"; import { observer } from "mobx-react"; import React, { FC, useCallback, useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; -import GlobeOrMap from "../../../Models/GlobeOrMap"; -import { ICredit } from "../Credit.type"; -import { Credits } from "../Credits"; -import { CreditsContainer } from "../CreditsContainer"; -import { DataAttributionModal } from "../DataAttribution/DataAttributionModal"; -import { Spacer } from "../Spacer"; -import { TerriaLogo } from "../TerriaLogo"; +import GlobeOrMap from "../../../../Models/GlobeOrMap"; +import { ICredit } from "./Credit.type"; +import { Credits } from "./Credits"; +import { CreditsContainer } from "./CreditsContainer"; +import { DataAttributionModal } from "./DataAttribution/DataAttributionModal"; +import { Spacer } from "./Spacer"; +import { TerriaLogo } from "./TerriaLogo"; import { MapCreditLogo } from "./MapCreditLogo"; interface IMapCreditsProps { diff --git a/lib/ReactViews/Credits/Spacer.tsx b/lib/ReactViews/Map/BottomBar/Credits/Spacer.tsx similarity index 100% rename from lib/ReactViews/Credits/Spacer.tsx rename to lib/ReactViews/Map/BottomBar/Credits/Spacer.tsx diff --git a/lib/ReactViews/Credits/TerriaLogo.tsx b/lib/ReactViews/Map/BottomBar/Credits/TerriaLogo.tsx similarity index 71% rename from lib/ReactViews/Credits/TerriaLogo.tsx rename to lib/ReactViews/Map/BottomBar/Credits/TerriaLogo.tsx index ab56a9046ed..fd035fd8688 100644 --- a/lib/ReactViews/Credits/TerriaLogo.tsx +++ b/lib/ReactViews/Map/BottomBar/Credits/TerriaLogo.tsx @@ -1,7 +1,7 @@ import React, { FC } from "react"; -import Box from "../../Styled/Box"; +import Box from "../../../../Styled/Box"; -const logo = require("../../../wwwroot/images/terria-watermark.svg"); +const logo = require("../../../../../wwwroot/images/terria-watermark.svg"); export const TerriaLogo: FC = () => { return ( diff --git a/lib/ReactViews/Map/BottomBar/Credits/index.ts b/lib/ReactViews/Map/BottomBar/Credits/index.ts new file mode 100644 index 00000000000..ebd9ea095ca --- /dev/null +++ b/lib/ReactViews/Map/BottomBar/Credits/index.ts @@ -0,0 +1,2 @@ +export { ICredit } from "./Credit.type"; +export { MapCredits } from "./MapCredits"; diff --git a/lib/ReactViews/Map/BottomBar/DistanceLegend.tsx b/lib/ReactViews/Map/BottomBar/DistanceLegend.tsx new file mode 100644 index 00000000000..6236d49259f --- /dev/null +++ b/lib/ReactViews/Map/BottomBar/DistanceLegend.tsx @@ -0,0 +1,243 @@ +"use strict"; +import L from "leaflet"; +import { runInAction } from "mobx"; +import { observer } from "mobx-react"; +import React, { FC, useEffect, useState, memo } from "react"; +import { useTheme } from "styled-components"; +import Cartesian2 from "terriajs-cesium/Source/Core/Cartesian2"; +import EllipsoidGeodesic from "terriajs-cesium/Source/Core/EllipsoidGeodesic"; +import CesiumEvent from "terriajs-cesium/Source/Core/Event"; +import getTimestamp from "terriajs-cesium/Source/Core/getTimestamp"; +import Scene from "terriajs-cesium/Source/Scene/Scene"; +import isDefined from "../../../Core/isDefined"; +import Box from "../../../Styled/Box"; +import Text from "../../../Styled/Text"; +import { useViewState } from "../../Context"; + +const geodesic = new EllipsoidGeodesic(); + +const distances = [ + 1, + 2, + 3, + 5, + 10, + 20, + 30, + 50, + 100, + 200, + 300, + 500, + 1000, + 2000, + 3000, + 5000, + 10000, + 20000, + 30000, + 50000, + 100000, + 200000, + 300000, + 500000, + 1000000, + 2000000, + 3000000, + 5000000, + 10000000, + 20000000, + 30000000, + 50000000 +]; + +interface IDistanceLegendProps { + scale?: number; + isPrintMode?: boolean; +} + +export const DistanceLegend: FC = observer( + ({ scale = 1, isPrintMode = false }) => { + const [distanceLabel, setDistanceLabel] = useState(); + const [barWidth, setBarWidth] = useState(0); + + const { terria } = useViewState(); + const theme = useTheme(); + + let removeUpdateSubscription: + | CesiumEvent.RemoveCallback + | (() => void) + | undefined; + + useEffect(() => { + const viewerSubscriptions: CesiumEvent.RemoveCallback[] = []; + + removeUpdateSubscription = addUpdateSubscription(); + + return () => { + if (removeUpdateSubscription) { + removeUpdateSubscription(); + } + viewerSubscriptions.forEach(clear => clear()); + }; + }, [terria.cesium, terria.leaflet]); + + const addUpdateSubscription = (): + | CesiumEvent.RemoveCallback + | (() => void) + | undefined => { + if (isDefined(terria.cesium)) { + const scene = terria.cesium.scene; + let removeUpdateSubscription: + | CesiumEvent.RemoveCallback + | undefined = scene.postRender.addEventListener(() => { + updateDistanceLegendCesium(scene); + if (isPrintMode) { + removeUpdateSubscription?.(); + removeUpdateSubscription = undefined; + } + }); + return removeUpdateSubscription; + } else if (isDefined(terria.leaflet)) { + const map = terria.leaflet.map; + let removeUpdateSubscription: (() => void) | undefined = undefined; + + if (!isPrintMode) { + const potentialChangeCallback = function potentialChangeCallback() { + updateDistanceLegendLeaflet(map); + }; + removeUpdateSubscription = function() { + map.off("zoomend", potentialChangeCallback); + map.off("moveend", potentialChangeCallback); + }; + + map.on("zoomend", potentialChangeCallback); + map.on("moveend", potentialChangeCallback); + } + + updateDistanceLegendLeaflet(map); + return removeUpdateSubscription; + } + }; + + const updateDistanceLegendCesium = (scene: Scene) => { + const now = getTimestamp(); + + // Find the distance between two pixels at the bottom center of the screen. + const width = scene.canvas.clientWidth; + const height = scene.canvas.clientHeight; + + const left = scene.camera.getPickRay( + new Cartesian2((width / 2) | 0, height - 1) + ); + const right = scene.camera.getPickRay( + new Cartesian2((1 + width / 2) | 0, height - 1) + ); + + const globe = scene.globe; + + if (!isDefined(left) || !isDefined(right)) { + return; + } + + const leftPosition = globe.pick(left, scene); + const rightPosition = globe.pick(right, scene); + + if (!isDefined(leftPosition) || !isDefined(rightPosition)) { + setBarWidth(0); + setDistanceLabel(undefined); + return; + } + + const leftCartographic = globe.ellipsoid.cartesianToCartographic( + leftPosition + ); + const rightCartographic = globe.ellipsoid.cartesianToCartographic( + rightPosition + ); + + geodesic.setEndPoints(leftCartographic, rightCartographic); + const pixelDistance = geodesic.surfaceDistance; + runInAction(() => (terria.mainViewer.scale = pixelDistance)); + + // Find the first distance that makes the scale bar less than 100 pixels. + const maxBarWidth = 100; + let distance; + for (let i = distances.length - 1; !isDefined(distance) && i >= 0; --i) { + if (distances[i] / pixelDistance < maxBarWidth) { + distance = distances[i]; + } + } + + if (isDefined(distance)) { + let label; + if (distance >= 1000) { + label = (distance / 1000).toString() + " km"; + } else { + label = distance.toString() + " m"; + } + setBarWidth(((distance / pixelDistance) * scale) | 0); + setDistanceLabel(label); + } else { + setBarWidth(0); + setDistanceLabel(undefined); + } + }; + + const updateDistanceLegendLeaflet = (map: L.Map) => { + const halfHeight = map.getSize().y / 2; + const maxPixelWidth = 100; + const maxMeters = map + .containerPointToLatLng([0, halfHeight]) + .distanceTo(map.containerPointToLatLng([maxPixelWidth, halfHeight])); + + runInAction(() => (terria.mainViewer.scale = maxMeters / 100)); + // @ts-ignore + const meters = L.control.scale()._getRoundNum(maxMeters); + const label = meters < 1000 ? meters + " m" : meters / 1000 + " km"; + + setBarWidth((meters / maxMeters) * maxPixelWidth * scale); + setDistanceLabel(label); + }; + + const barStyle = { + width: barWidth + "px", + left: 5 + (125 - barWidth) / 2 + "px", + height: "2px" + }; + + return distanceLabel ? ( + + + {distanceLabel} + +
+ + ) : null; + } +); diff --git a/lib/ReactViews/Map/BottomBar/LocationBar.tsx b/lib/ReactViews/Map/BottomBar/LocationBar.tsx new file mode 100644 index 00000000000..67ee4c5798b --- /dev/null +++ b/lib/ReactViews/Map/BottomBar/LocationBar.tsx @@ -0,0 +1,88 @@ +import { observer } from "mobx-react"; +import React, { FC } from "react"; +import { useTranslation } from "react-i18next"; +import styled, { useTheme } from "styled-components"; +import MouseCoords from "../../../ReactViewModels/MouseCoords"; +import Box from "../../../Styled/Box"; +import { RawButton } from "../../../Styled/Button"; +import { TextSpan } from "../../../Styled/Text"; + +interface ILocationBarProps { + mouseCoords: MouseCoords; +} + +const Section = styled(Box).attrs({ + paddedHorizontally: true +})``; + +const StyledText = styled(TextSpan).attrs({ + textLight: true, + mono: true, + noWrap: true +})` + font-size: 0.7rem; + padding: 0 5px 0 5px; +`; + +export const LocationBar: FC = observer( + ({ mouseCoords }) => { + const theme = useTheme(); + const { t } = useTranslation(); + + return ( + + + {!mouseCoords.useProjection ? ( + <> +
+ {t("legend.lat")} + {mouseCoords.latitude} +
+
+ {t("legend.lon")} + {mouseCoords.longitude} +
+ + ) : ( + <> +
+ {t("legend.zone")} + {mouseCoords.utmZone} +
+
+ {t("legend.e")} + {mouseCoords.east} +
+
+ {t("legend.n")} + {mouseCoords.north} +
+ + )} +
+ {t("legend.elev")} + {mouseCoords.elevation} +
+
+
+ ); + } +); diff --git a/lib/ReactViews/Map/BottomBar/index.ts b/lib/ReactViews/Map/BottomBar/index.ts new file mode 100644 index 00000000000..c8b81e2ff08 --- /dev/null +++ b/lib/ReactViews/Map/BottomBar/index.ts @@ -0,0 +1 @@ +export { BottomBar } from "./BottomBar"; diff --git a/lib/ReactViews/Map/BottomLeftBar/BottomLeftBar.tsx b/lib/ReactViews/Map/BottomLeftBar/BottomLeftBar.tsx index 8099e7325da..c4440c11864 100644 --- a/lib/ReactViews/Map/BottomLeftBar/BottomLeftBar.tsx +++ b/lib/ReactViews/Map/BottomLeftBar/BottomLeftBar.tsx @@ -1,4 +1,4 @@ -import React from "react"; +import React, { FC } from "react"; import { useTranslation } from "react-i18next"; import ViewState from "../../../ReactViewModels/ViewState"; @@ -10,47 +10,43 @@ import MapDataCount from "../../BottomDock/MapDataCount"; import Terria from "../../../Models/Terria"; import MapIconButton from "../../MapIconButton/MapIconButton"; import defined from "terriajs-cesium/Source/Core/defined"; - -interface Props { - terria: Terria; - viewState: ViewState; -} +import { useViewState } from "../../Context"; const BottomLeftContainer = styled(Box)` position: absolute; bottom: 40px; - @media (max-width: ${props => props.theme.mobile}px) { bottom: 35px; } `; -const shouldShowPlayStoryButton = (props: Props) => - props.terria.configParameters.storyEnabled && - defined(props.terria.stories) && - props.terria.stories.length > 0 && - props.viewState.useSmallScreenInterface; +const shouldShowPlayStoryButton = (viewState: ViewState) => + viewState.terria.configParameters.storyEnabled && + defined(viewState.terria.stories) && + viewState.terria.stories.length > 0 && + viewState.useSmallScreenInterface; -const BottomLeftBar = (props: Props) => { +const BottomLeftBar: FC = () => { const { t } = useTranslation(); const theme = useTheme(); + const viewState = useViewState(); const isNotificationActive = - props.terria.notificationState.currentNotification; + viewState.terria.notificationState.currentNotification; return ( - {shouldShowPlayStoryButton(props) ? ( + {shouldShowPlayStoryButton(viewState) ? ( } - onClick={() => props.viewState.runStories()} + onClick={() => viewState.runStories()} primary={!isNotificationActive} > {t("story.playStory")} diff --git a/lib/ReactViews/Map/HelpButton/help-button.scss b/lib/ReactViews/Map/HelpButton/help-button.scss deleted file mode 100644 index c89132566d1..00000000000 --- a/lib/ReactViews/Map/HelpButton/help-button.scss +++ /dev/null @@ -1,4 +0,0 @@ -.helpBtn { - composes: btn from "../../../Sass/common/_buttons.scss"; - composes: btn--map from "../../../Sass/common/_buttons.scss"; -} diff --git a/lib/ReactViews/Map/Legend/DistanceLegend.jsx b/lib/ReactViews/Map/Legend/DistanceLegend.jsx deleted file mode 100644 index e163b318901..00000000000 --- a/lib/ReactViews/Map/Legend/DistanceLegend.jsx +++ /dev/null @@ -1,233 +0,0 @@ -"use strict"; -import React from "react"; -import PropTypes from "prop-types"; -import L from "leaflet"; -import Cartesian2 from "terriajs-cesium/Source/Core/Cartesian2"; -import defined from "terriajs-cesium/Source/Core/defined"; -import EllipsoidGeodesic from "terriajs-cesium/Source/Core/EllipsoidGeodesic"; -import getTimestamp from "terriajs-cesium/Source/Core/getTimestamp"; -import Styles from "./legend.scss"; -import { observer, disposeOnUnmount } from "mobx-react"; -import { autorun, runInAction } from "mobx"; - -const geodesic = new EllipsoidGeodesic(); - -const distances = [ - 1, - 2, - 3, - 5, - 10, - 20, - 30, - 50, - 100, - 200, - 300, - 500, - 1000, - 2000, - 3000, - 5000, - 10000, - 20000, - 30000, - 50000, - 100000, - 200000, - 300000, - 500000, - 1000000, - 2000000, - 3000000, - 5000000, - 10000000, - 20000000, - 30000000, - 50000000 -]; - -@observer -class DistanceLegend extends React.Component { - constructor(props) { - super(props); - this.state = { - distanceLabel: undefined, - barWidth: 0 - }; - } - static displayName = "DistanceLegend"; - static propTypes = { - terria: PropTypes.object, - scale: PropTypes.number, - isPrintMode: PropTypes.bool - }; - - /* eslint-disable-next-line camelcase */ - UNSAFE_componentWillMount() { - this.viewerSubscriptions = []; - this.removeUpdateSubscription = undefined; - - this._lastLegendUpdate = undefined; - this.viewerSubscriptions.push( - this.props.terria.mainViewer.beforeViewerChanged.addEventListener(() => { - if (defined(this.removeUpdateSubscription)) { - this.removeUpdateSubscription(); - this.removeUpdateSubscription = undefined; - } - }) - ); - disposeOnUnmount( - this, - autorun(() => this.addUpdateSubscription()) - ); - } - - componentWillUnmount() { - this.removeUpdateSubscription && this.removeUpdateSubscription(); - this.viewerSubscriptions.forEach(remove => remove()); - } - - addUpdateSubscription() { - const that = this; - if (defined(this.props.terria.cesium)) { - const scene = this.props.terria.cesium.scene; - this.removeUpdateSubscription = scene.postRender.addEventListener(() => { - this.updateDistanceLegendCesium(scene); - if (this.props.isPrintMode) { - this.removeUpdateSubscription(); - this.removeUpdateSubscription = null; - } - }); - } else if (defined(this.props.terria.leaflet)) { - const map = this.props.terria.leaflet.map; - - const potentialChangeCallback = function potentialChangeCallback() { - that.updateDistanceLegendLeaflet(map); - }; - if (!this.props.isPrintMode) { - that.removeUpdateSubscription = function() { - map.off("zoomend", potentialChangeCallback); - map.off("moveend", potentialChangeCallback); - }; - - map.on("zoomend", potentialChangeCallback); - map.on("moveend", potentialChangeCallback); - } - - that.updateDistanceLegendLeaflet(map); - } - } - - updateDistanceLegendCesium(scene) { - const now = getTimestamp(); - if (now < this._lastLegendUpdate + 250) { - return; - } - - this._lastLegendUpdate = now; - - // Find the distance between two pixels at the bottom center of the screen. - const width = scene.canvas.clientWidth; - const height = scene.canvas.clientHeight; - - const left = scene.camera.getPickRay( - new Cartesian2((width / 2) | 0, height - 1) - ); - const right = scene.camera.getPickRay( - new Cartesian2((1 + width / 2) | 0, height - 1) - ); - - const globe = scene.globe; - const leftPosition = globe.pick(left, scene); - const rightPosition = globe.pick(right, scene); - - if (!defined(leftPosition) || !defined(rightPosition)) { - this.setState({ - barWidth: undefined, - distanceLabel: undefined - }); - return; - } - - const leftCartographic = globe.ellipsoid.cartesianToCartographic( - leftPosition - ); - const rightCartographic = globe.ellipsoid.cartesianToCartographic( - rightPosition - ); - - geodesic.setEndPoints(leftCartographic, rightCartographic); - const pixelDistance = geodesic.surfaceDistance; - runInAction(() => (this.props.terria.mainViewer.scale = pixelDistance)); - - // Find the first distance that makes the scale bar less than 100 pixels. - const maxBarWidth = 100; - let distance; - for (let i = distances.length - 1; !defined(distance) && i >= 0; --i) { - if (distances[i] / pixelDistance < maxBarWidth) { - distance = distances[i]; - } - } - - if (defined(distance)) { - let label; - if (distance >= 1000) { - label = (distance / 1000).toString() + " km"; - } else { - label = distance.toString() + " m"; - } - - this.setState({ - barWidth: ((distance / pixelDistance) * this.props.scale) | 0, - distanceLabel: label - }); - } else { - this.setState({ - barWidth: undefined, - distanceLabel: undefined - }); - } - } - - updateDistanceLegendLeaflet(map) { - const halfHeight = map.getSize().y / 2; - const maxPixelWidth = 100; - const maxMeters = map - .containerPointToLatLng([0, halfHeight]) - .distanceTo(map.containerPointToLatLng([maxPixelWidth, halfHeight])); - - runInAction(() => (this.props.terria.mainViewer.scale = maxMeters / 100)); - - const meters = L.control.scale()._getRoundNum(maxMeters); - const label = meters < 1000 ? meters + " m" : meters / 1000 + " km"; - - this.setState({ - barWidth: (meters / maxMeters) * maxPixelWidth * this.props.scale, - distanceLabel: label - }); - } - - render() { - const barStyle = { - width: this.state.barWidth + "px", - left: 5 + (125 - this.state.barWidth) / 2 + "px", - height: "2px" - }; - - const distanceLabel = this.state.distanceLabel ? ( -
- -
-
- ) : null; - - return distanceLabel; - } -} -DistanceLegend.defaultProps = { - scale: 1, - isPrintMode: false -}; - -export default DistanceLegend; diff --git a/lib/ReactViews/Map/Legend/LocationBar.jsx b/lib/ReactViews/Map/Legend/LocationBar.jsx deleted file mode 100644 index 47ea185d906..00000000000 --- a/lib/ReactViews/Map/Legend/LocationBar.jsx +++ /dev/null @@ -1,82 +0,0 @@ -"use strict"; -import classNames from "classnames"; -import createReactClass from "create-react-class"; -import { observer } from "mobx-react"; -import PropTypes from "prop-types"; -import { withTranslation } from "react-i18next"; -import React from "react"; -import Styles from "./legend.scss"; - -const LocationBar = observer( - createReactClass({ - displayName: "LocationBar", - - propTypes: { - terria: PropTypes.object, - showUtmZone: PropTypes.bool, - mouseCoords: PropTypes.object.isRequired, - t: PropTypes.func.isRequired - }, - - getDefaultProps: function() { - return { - showUtmZone: true - }; - }, - - toggleUseProjection() { - this.props.mouseCoords.toggleUseProjection(); - }, - - render() { - const { t } = this.props; - return ( - - ); - } - }) -); - -module.exports = withTranslation()(LocationBar); diff --git a/lib/ReactViews/Map/Legend/legend.scss b/lib/ReactViews/Map/Legend/legend.scss deleted file mode 100644 index 58110a76b6e..00000000000 --- a/lib/ReactViews/Map/Legend/legend.scss +++ /dev/null @@ -1,75 +0,0 @@ -@import "~terriajs-variables"; -@import "../../../Sass/common/mixins"; - -$distance-bg: rgba($dark, 0.9); - -.baseLegend { - box-sizing: border-box; - font-family: $font-base; - float: left; - background-color: #fff; - color: $text-dark; - padding: $padding-small $padding-small; - font-size: $font-size-mid-mini; - text-align: center; - line-height: 1; - border: 0; - outline: 0; - font-family: $font-mono; - max-height: 21px; - margin-top: $padding-mini; - &:hover { - background: $faint-bg; - } - - .bar { - background: #fff; - margin: 0 auto; - display: block; - @include transition(all 0.5s ease-in-out); - } -} - -.locationBar, -.distanceLegend { - composes: baseLegend; - // Adjust colors to match btn--map. - background-color: unset; - margin-bottom: $padding-mini; - color: $text-light; - &:hover { - // background: $color-primary; - } - // - margin-right: $padding-small; - span { - padding: 0 $padding-small; - } - - li, - div { - display: inline-block; - padding: 0 $padding-small; - text-align: left; - } - - .section-long { - width: 130px; - } - - .section { - width: 112px; - } - - .section-short { - width: 70px; - } -} - -.distanceLegend { - &:hover { - background: $charcoal-grey; - } - text-align: center; - width: 110px; -} diff --git a/lib/ReactViews/Map/Legend/legend.scss.d.ts b/lib/ReactViews/Map/Legend/legend.scss.d.ts deleted file mode 100644 index 2216fd3b3ba..00000000000 --- a/lib/ReactViews/Map/Legend/legend.scss.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -// This file is automatically generated. -// Please do not change this file! -interface CssExports { - 'bar': string; - 'baseLegend': string; - 'distanceLegend': string; - 'locationBar': string; - 'section': string; - 'section-long': string; - 'section-short': string; - 'sectionLong': string; - 'sectionShort': string; -} -declare var cssExports: CssExports; -export = cssExports; diff --git a/lib/ReactViews/Map/MapColumn.tsx b/lib/ReactViews/Map/MapColumn.tsx new file mode 100644 index 00000000000..25f647c9164 --- /dev/null +++ b/lib/ReactViews/Map/MapColumn.tsx @@ -0,0 +1,136 @@ +import { observer } from "mobx-react"; +import React, { FC } from "react"; +import { useTranslation } from "react-i18next"; +import Box from "../../Styled/Box"; +import BottomDock from "../BottomDock/BottomDock"; +import { useViewState } from "../Context"; +import Loader from "../Loader"; +import SlideUpFadeIn from "../Transitions/SlideUpFadeIn/SlideUpFadeIn"; +import { BottomBar } from "./BottomBar"; +import BottomLeftBar from "./BottomLeftBar/BottomLeftBar"; +import { MapNavigation } from "./MapNavigation"; +import MenuBar from "./MenuBar/MenuBar"; +import { ProgressBar } from "./ProgressBar"; +import { TerriaViewerWrapper } from "./TerriaViewerWrapper"; +import Toast from "./Toast"; + +interface IMapColumnProps { + customFeedbacks: any; + animationDuration: number; + customElements: any; +} + +/** + * Right-hand column that contains the map, controls that sit over the map and sometimes the bottom dock containing + * the timeline and charts. + */ +export const MapColumn: FC = observer( + ({ customFeedbacks, customElements, animationDuration }) => { + const viewState = useViewState(); + const { t } = useTranslation(); + + return ( + + +
+ +
+ {!viewState.hideMapUi && ( + <> + + + + )} + + + + {!viewState.hideMapUi && ( + <> + + + + + + + + + + + {viewState.terria.configParameters.printDisclaimer && ( + + {viewState.terria.configParameters.printDisclaimer.text} + + )} + + )} +
+
+ {true && ( + + )} +
+
+ ); + } +); + +export default MapColumn; diff --git a/lib/ReactViews/Map/Navigation/Items/OverflowNavigationItem.tsx b/lib/ReactViews/Map/MapNavigation/CollapsedNavigation.tsx similarity index 84% rename from lib/ReactViews/Map/Navigation/Items/OverflowNavigationItem.tsx rename to lib/ReactViews/Map/MapNavigation/CollapsedNavigation.tsx index 78e2ee980cc..b43925c5d84 100644 --- a/lib/ReactViews/Map/Navigation/Items/OverflowNavigationItem.tsx +++ b/lib/ReactViews/Map/MapNavigation/CollapsedNavigation.tsx @@ -3,16 +3,16 @@ import { observer } from "mobx-react"; import React, { useEffect } from "react"; import { useTranslation } from "react-i18next"; import styled, { useTheme } from "styled-components"; -import { applyTranslationIfExists } from "../../../../Language/languageHelpers"; -import Box, { BoxSpan } from "../../../../Styled/Box"; -import { StyledIcon } from "../../../../Styled/Icon"; -import Spacing from "../../../../Styled/Spacing"; -import Text from "../../../../Styled/Text"; -import { IMapNavigationItem } from "../../../../ViewModels/MapNavigation/MapNavigationModel"; -import CloseButton from "../../../Generic/CloseButton"; -import { PrefaceBox } from "../../../Generic/PrefaceBox"; -import { useViewState } from "../../../StandardUserInterface/ViewStateContext"; -import { filterViewerAndScreenSize } from "../MapNavigation"; +import { applyTranslationIfExists } from "../../../Language/languageHelpers"; +import Box, { BoxSpan } from "../../../Styled/Box"; +import { StyledIcon } from "../../../Styled/Icon"; +import Spacing from "../../../Styled/Spacing"; +import Text from "../../../Styled/Text"; +import { IMapNavigationItem } from "../../../ViewModels/MapNavigation/MapNavigationModel"; +import { useViewState } from "../../Context"; +import CloseButton from "../../Generic/CloseButton"; +import { PrefaceBox } from "../../Generic/PrefaceBox"; +import { filterViewerAndScreenSize } from "./filterViewerAndScreenSize"; interface PropTypes { items: IMapNavigationItem[]; @@ -128,7 +128,7 @@ const CollapsedNavigationPanel: React.FC = observer( ); const CollapsedNavigationDisplayName = "CollapsedNavigation"; -const CollapsedNavigation: React.FC = observer(() => { +export const CollapsedNavigation: React.FC = observer(() => { const viewState = useViewState(); useEffect(() => autorun(() => { @@ -163,5 +163,3 @@ const CollapsedNavigation: React.FC = observer(() => { ); }); - -export default CollapsedNavigation; diff --git a/lib/ReactViews/Map/Navigation/Items/AugmentedVirtualityTool.tsx b/lib/ReactViews/Map/MapNavigation/Items/AugmentedVirtualityTool.tsx similarity index 100% rename from lib/ReactViews/Map/Navigation/Items/AugmentedVirtualityTool.tsx rename to lib/ReactViews/Map/MapNavigation/Items/AugmentedVirtualityTool.tsx diff --git a/lib/ReactViews/Map/Navigation/Items/CatalogShortcut.jsx b/lib/ReactViews/Map/MapNavigation/Items/CatalogShortcut.jsx similarity index 100% rename from lib/ReactViews/Map/Navigation/Items/CatalogShortcut.jsx rename to lib/ReactViews/Map/MapNavigation/Items/CatalogShortcut.jsx diff --git a/lib/ReactViews/Map/Navigation/Items/CloseToolButton.tsx b/lib/ReactViews/Map/MapNavigation/Items/CloseToolButton.tsx similarity index 65% rename from lib/ReactViews/Map/Navigation/Items/CloseToolButton.tsx rename to lib/ReactViews/Map/MapNavigation/Items/CloseToolButton.tsx index 719b03526d0..377e116533d 100644 --- a/lib/ReactViews/Map/Navigation/Items/CloseToolButton.tsx +++ b/lib/ReactViews/Map/MapNavigation/Items/CloseToolButton.tsx @@ -1,15 +1,12 @@ -import React from "react"; -import { withTranslation, WithTranslation } from "react-i18next"; -import ViewState from "../../../../ReactViewModels/ViewState"; +import React, { FC } from "react"; +import { useTranslation } from "react-i18next"; import Icon from "../../../../Styled/Icon"; +import { useViewState } from "../../../Context"; import MapIconButton from "../../../MapIconButton/MapIconButton"; -interface PropsType extends WithTranslation { - viewState: ViewState; - t: any; -} - -function CloseToolButton({ viewState, t }: PropsType) { +export const CloseToolButton: FC = () => { + const { t } = useTranslation(); + const viewState = useViewState(); const closeText = t("tool.closeButtonTitle", { toolName: viewState.currentTool?.toolName }); @@ -31,6 +28,4 @@ function CloseToolButton({ viewState, t }: PropsType) { {closeText} ); -} - -export default withTranslation()(CloseToolButton); +}; diff --git a/lib/ReactViews/Map/Navigation/Items/Compass.tsx b/lib/ReactViews/Map/MapNavigation/Items/Compass/Compass.tsx similarity index 94% rename from lib/ReactViews/Map/Navigation/Items/Compass.tsx rename to lib/ReactViews/Map/MapNavigation/Items/Compass/Compass.tsx index e25167822b7..22206c308dd 100644 --- a/lib/ReactViews/Map/Navigation/Items/Compass.tsx +++ b/lib/ReactViews/Map/MapNavigation/Items/Compass/Compass.tsx @@ -23,21 +23,21 @@ import CesiumMath from "terriajs-cesium/Source/Core/Math"; import Matrix4 from "terriajs-cesium/Source/Core/Matrix4"; import Ray from "terriajs-cesium/Source/Core/Ray"; import Transforms from "terriajs-cesium/Source/Core/Transforms"; -import isDefined from "../../../../Core/isDefined"; -import Terria from "../../../../Models/Terria"; -import ViewState from "../../../../ReactViewModels/ViewState"; -import Box from "../../../../Styled/Box"; -import Icon, { StyledIcon } from "../../../../Styled/Icon"; -import GyroscopeGuidance from "../../../GyroscopeGuidance/GyroscopeGuidance"; -import { withTerriaRef } from "../../../HOCs/withTerriaRef"; -import FadeIn from "../../../Transitions/FadeIn/FadeIn"; +import isDefined from "../../../../../Core/isDefined"; +import Terria from "../../../../../Models/Terria"; +import ViewState from "../../../../../ReactViewModels/ViewState"; +import Box from "../../../../../Styled/Box"; +import Icon, { StyledIcon } from "../../../../../Styled/Icon"; +import { GyroscopeGuidance } from "./GyroscopeGuidance"; +import { withTerriaRef } from "../../../../HOCs/withTerriaRef"; +import FadeIn from "../../../../Transitions/FadeIn/FadeIn"; const CameraFlightPath = require("terriajs-cesium/Source/Scene/CameraFlightPath") .default; export const COMPASS_LOCAL_PROPERTY_KEY = "CompassHelpPrompted"; -// Map Compass +// Map CompassBase // // Markup: // @@ -63,7 +63,7 @@ const StyledCompass = styled.div` `; /** - * Take a compass width and scale it up 10px, instead of hardcoding values like: + * Take a compassbase width and scale it up 10px, instead of hardcoding values like: * // const compassScaleRatio = 66 / 56; */ const getCompassScaleRatio = (compassWidth: string) => @@ -80,7 +80,7 @@ const getCompassScaleRatio = (compassWidth: string) => * - chrome (not even another webkit browser) * - "default browser zoom" (doesn't happen when you are even at 110%, but will * when shrunk down enough) - * - the way our compass is composed + * - the way our compassbase is composed * * The action of triggering the 'active' state (scaled up to * `getCompassScaleRatio()`) & back down means that the "InnerRing" will look @@ -88,10 +88,10 @@ const getCompassScaleRatio = (compassWidth: string) => * chrome will decide to render it in the correct position. * * I haven't dug further to the root cause as doing it like this means wew now - * have a beautiful animating compass. + * have a beautiful animating compassbase. * * So please leave scale(0.9999) alone unless you can fix the rendering issue in - * chrome, or if you want to develop a burning hatred for the compass 🙏🔥 + * chrome, or if you want to develop a burning hatred for the compassbase 🙏🔥 * **/ const StyledCompassOuterRing = styled.div` @@ -149,8 +149,8 @@ type IStateTypes = { activeForTransition: boolean; }; -// the compass on map -class Compass extends React.Component { +// the compassbase on map +class CompassBase extends React.Component { _unsubscribeFromPostRender: any; _unsubscribeFromAnimationFrame: any; private _unsubscribeFromViewerChange?: CesiumEvent.RemoveCallback; @@ -325,7 +325,7 @@ class Compass extends React.Component { }; const { t } = this.props; const active = this.state.active; - const description = t("compass.description"); + const description = t("compassbase.description"); const showGuidance = !this.props.viewState.terria.getLocalProperty( COMPASS_LOCAL_PROPERTY_KEY ); @@ -368,7 +368,7 @@ class Compass extends React.Component { {/* "Center circle icon" */} - + { this.setState({ active: true })} onMouseOut={() => { @@ -443,7 +443,7 @@ const windowPositionScratch = new Cartesian2(); const pickRayScratch = new Ray(); function rotate( - viewModel: Compass, + viewModel: CompassBase, compassElement: Element, cursorVector: Cartesian2 ) { @@ -568,7 +568,7 @@ function rotate( } function orbit( - viewModel: Compass, + viewModel: CompassBase, compassElement: Element, cursorVector: Cartesian2 ) { @@ -732,7 +732,7 @@ function orbit( ); } -function subscribeToAnimationFrame(viewModel: Compass) { +function subscribeToAnimationFrame(viewModel: CompassBase) { viewModel._unsubscribeFromAnimationFrame = (id => () => cancelAnimationFrame(id))( requestAnimationFrame(() => { @@ -744,7 +744,7 @@ function subscribeToAnimationFrame(viewModel: Compass) { ); } -function viewerChange(viewModel: Compass) { +function viewerChange(viewModel: CompassBase) { runInAction(() => { if (isDefined(viewModel.props.terria.cesium)) { if (viewModel._unsubscribeFromPostRender) { @@ -772,7 +772,7 @@ function viewerChange(viewModel: Compass) { } export const COMPASS_NAME = "MapNavigationCompassOuterRing"; -export const COMPASS_TOOL_ID = "compass"; -export default withTranslation()( - withTheme(withTerriaRef(Compass, COMPASS_NAME)) +export const COMPASS_TOOL_ID = "compassbase"; +export const Compass = withTranslation()( + withTheme(withTerriaRef(CompassBase, COMPASS_NAME)) ); diff --git a/lib/ReactViews/GyroscopeGuidance/GyroscopeGuidance.jsx b/lib/ReactViews/Map/MapNavigation/Items/Compass/GyroscopeGuidance.jsx similarity index 91% rename from lib/ReactViews/GyroscopeGuidance/GyroscopeGuidance.jsx rename to lib/ReactViews/Map/MapNavigation/Items/Compass/GyroscopeGuidance.jsx index 88abd356266..329ca1f50fc 100644 --- a/lib/ReactViews/GyroscopeGuidance/GyroscopeGuidance.jsx +++ b/lib/ReactViews/Map/MapNavigation/Items/Compass/GyroscopeGuidance.jsx @@ -3,15 +3,15 @@ import styled, { css } from "styled-components"; import PropTypes from "prop-types"; import { useTranslation } from "react-i18next"; -import Icon from "../../Styled/Icon"; -import Box from "../../Styled/Box"; -import { TextSpan } from "../../Styled/Text"; -import { RawButton } from "../../Styled/Button"; -import Spacing from "../../Styled/Spacing"; -import MapIconButton from "../MapIconButton/MapIconButton"; +import Icon from "../../../../../Styled/Icon"; +import Box from "../../../../../Styled/Box"; +import { TextSpan } from "../../../../../Styled/Text"; +import { RawButton } from "../../../../../Styled/Button"; +import Spacing from "../../../../../Styled/Spacing"; +import MapIconButton from "../../../../MapIconButton/MapIconButton"; // import MenuPanel from "../StandardUserInterface/customizable/MenuPanel"; -import CleanDropdownPanel from "../CleanDropdownPanel/CleanDropdownPanel"; -import { COMPASS_LOCAL_PROPERTY_KEY } from "../Map/Navigation/Items/Compass"; +import CleanDropdownPanel from "../../../../CleanDropdownPanel/CleanDropdownPanel"; +import { COMPASS_LOCAL_PROPERTY_KEY } from "./Compass"; GyroscopeGuidance.propTypes = { viewState: PropTypes.object.isRequired, @@ -129,7 +129,7 @@ GyroscopeGuidancePanel.propTypes = { onClose: PropTypes.func.isRequired }; -export default function GyroscopeGuidance(props) { +export function GyroscopeGuidance(props) { const [controlPanelOpen, setControlPanelOpen] = useState(false); const controlsMapIcon = useRef(); const { t } = useTranslation(); diff --git a/lib/ReactViews/Map/MapNavigation/Items/Compass/index.ts b/lib/ReactViews/Map/MapNavigation/Items/Compass/index.ts new file mode 100644 index 00000000000..fca157c39b0 --- /dev/null +++ b/lib/ReactViews/Map/MapNavigation/Items/Compass/index.ts @@ -0,0 +1 @@ +export { Compass, COMPASS_TOOL_ID } from "./Compass"; diff --git a/lib/ReactViews/Map/Navigation/Items/MapNavigationItem.tsx b/lib/ReactViews/Map/MapNavigation/Items/MapNavigationItem.tsx similarity index 94% rename from lib/ReactViews/Map/Navigation/Items/MapNavigationItem.tsx rename to lib/ReactViews/Map/MapNavigation/Items/MapNavigationItem.tsx index 83e0ac7aa29..75e7591a82a 100644 --- a/lib/ReactViews/Map/Navigation/Items/MapNavigationItem.tsx +++ b/lib/ReactViews/Map/MapNavigation/Items/MapNavigationItem.tsx @@ -19,7 +19,7 @@ interface PropTypes { } @observer -class MapNavigationItem extends React.Component { +class MapNavigationItemBase extends React.Component { constructor(props: PropTypes) { super(props); } @@ -73,4 +73,4 @@ export const Control = styled(Box).attrs({ text-align: center; `; -export default withTranslation()(MapNavigationItem); +export const MapNavigationItem = withTranslation()(MapNavigationItemBase); diff --git a/lib/ReactViews/Map/Navigation/Items/MeasureTool.ts b/lib/ReactViews/Map/MapNavigation/Items/MeasureTool.ts similarity index 99% rename from lib/ReactViews/Map/Navigation/Items/MeasureTool.ts rename to lib/ReactViews/Map/MapNavigation/Items/MeasureTool.ts index c07fc0cab17..4aaa58bce46 100644 --- a/lib/ReactViews/Map/Navigation/Items/MeasureTool.ts +++ b/lib/ReactViews/Map/MapNavigation/Items/MeasureTool.ts @@ -21,7 +21,7 @@ interface MeasureToolOptions { onClose(): void; } -export default class MeasureTool extends MapNavigationItemController { +export class MeasureTool extends MapNavigationItemController { static id = "measure-tool"; static displayName = "MeasureTool"; diff --git a/lib/ReactViews/Map/Navigation/Items/MyLocation.ts b/lib/ReactViews/Map/MapNavigation/Items/MyLocation.ts similarity index 98% rename from lib/ReactViews/Map/Navigation/Items/MyLocation.ts rename to lib/ReactViews/Map/MapNavigation/Items/MyLocation.ts index 211da462262..300b97d82bd 100644 --- a/lib/ReactViews/Map/Navigation/Items/MyLocation.ts +++ b/lib/ReactViews/Map/MapNavigation/Items/MyLocation.ts @@ -19,7 +19,7 @@ interface PropTypes { terria: Terria; } -class MyLocation extends MapNavigationItemController { +export class MyLocation extends MapNavigationItemController { static id = "my-location"; static displayName = "MyLocation"; readonly terria: Terria; @@ -188,5 +188,3 @@ class MyLocation extends MapNavigationItemController { } } } - -export default MyLocation; diff --git a/lib/ReactViews/Map/Navigation/Items/ToggleSplitterTool.ts b/lib/ReactViews/Map/MapNavigation/Items/ToggleSplitterTool.ts similarity index 100% rename from lib/ReactViews/Map/Navigation/Items/ToggleSplitterTool.ts rename to lib/ReactViews/Map/MapNavigation/Items/ToggleSplitterTool.ts diff --git a/lib/ReactViews/Map/Navigation/Items/ToolButton.tsx b/lib/ReactViews/Map/MapNavigation/Items/ToolButton.tsx similarity index 100% rename from lib/ReactViews/Map/Navigation/Items/ToolButton.tsx rename to lib/ReactViews/Map/MapNavigation/Items/ToolButton.tsx diff --git a/lib/ReactViews/Map/Navigation/Items/ZoomControl.tsx b/lib/ReactViews/Map/MapNavigation/Items/ZoomControl.tsx similarity index 97% rename from lib/ReactViews/Map/Navigation/Items/ZoomControl.tsx rename to lib/ReactViews/Map/MapNavigation/Items/ZoomControl.tsx index 1e641ee161a..5b2eaf92563 100644 --- a/lib/ReactViews/Map/Navigation/Items/ZoomControl.tsx +++ b/lib/ReactViews/Map/MapNavigation/Items/ZoomControl.tsx @@ -17,7 +17,7 @@ import Box from "../../../../Styled/Box"; import { RawButton } from "../../../../Styled/Button"; import Icon, { GLYPHS } from "../../../../Styled/Icon"; import Ul, { Li } from "../../../../Styled/List"; -import Terria from "./../../../../Models/Terria"; +import Terria from "../../../../Models/Terria"; const Tween = require("terriajs-cesium/Source/ThirdParty/Tween").default; @@ -29,7 +29,7 @@ interface PropTypes extends WithTranslation { export const ZOOM_CONTROL_ID = "zoom"; -class ZoomControl extends React.Component { +class ZoomControlBase extends React.Component { static displayName = "ZoomControl"; constructor(props: PropTypes) { @@ -236,10 +236,9 @@ const StyledZoomControl = styled(Box).attrs(props => ({ width: 20px; fill: ${props => props.theme.darkWithOverlay}; } - ${Li} { margin: 5px 0; } `; -export default withTranslation()(withTheme(ZoomControl)); +export const ZoomControl = withTranslation()(withTheme(ZoomControlBase)); diff --git a/lib/ReactViews/Map/MapNavigation/Items/index.ts b/lib/ReactViews/Map/MapNavigation/Items/index.ts new file mode 100644 index 00000000000..7d28299b240 --- /dev/null +++ b/lib/ReactViews/Map/MapNavigation/Items/index.ts @@ -0,0 +1,14 @@ +export { + AR_TOOL_ID, + AugmentedVirtualityController, + AugmentedVirtualityHoverController, + AugmentedVirtualityRealign, + AugmentedVirtualityRealignController +} from "./AugmentedVirtualityTool"; +export { CloseToolButton } from "./CloseToolButton"; +export * from "./Compass"; +export { Control, MapNavigationItem } from "./MapNavigationItem"; +export { MeasureTool } from "./MeasureTool"; +export { MyLocation } from "./MyLocation"; +export { ToggleSplitterController } from "./ToggleSplitterTool"; +export { ZoomControl, ZOOM_CONTROL_ID } from "./ZoomControl"; diff --git a/lib/ReactViews/Map/Navigation/MapNavigation.tsx b/lib/ReactViews/Map/MapNavigation/MapNavigation.tsx similarity index 90% rename from lib/ReactViews/Map/Navigation/MapNavigation.tsx rename to lib/ReactViews/Map/MapNavigation/MapNavigation.tsx index f7c7ce7d06e..d66609c783f 100644 --- a/lib/ReactViews/Map/Navigation/MapNavigation.tsx +++ b/lib/ReactViews/Map/MapNavigation/MapNavigation.tsx @@ -12,7 +12,6 @@ import { observer } from "mobx-react"; import React from "react"; import { WithTranslation, withTranslation } from "react-i18next"; import styled, { DefaultTheme, withTheme } from "styled-components"; -import isDefined from "../../../Core/isDefined"; import ViewState from "../../../ReactViewModels/ViewState"; import Box from "../../../Styled/Box"; import Icon, { GLYPHS } from "../../../Styled/Icon"; @@ -22,9 +21,9 @@ import MapNavigationModel, { } from "../../../ViewModels/MapNavigation/MapNavigationModel"; import withControlledVisibility from "../../HOCs/withControlledVisibility"; import MapIconButton from "../../MapIconButton/MapIconButton"; -import MapNavigationItem, { Control } from "./Items/MapNavigationItem"; +import { filterViewerAndScreenSize } from "./filterViewerAndScreenSize"; +import { Control, MapNavigationItem } from "./Items"; import { registerMapNavigations } from "./registerMapNavigations"; -import { ScreenSize } from "../../../ViewModels/CompositeBar/CompositeBarModel"; const OVERFLOW_ACTION_SIZE = 42; @@ -55,11 +54,9 @@ const StyledMapNavigation = styled.div` } } pointer-events: none; - button { pointer-events: auto; } - ${p => p.trainerBarVisible && ` @@ -89,7 +86,7 @@ enum Orientation { } @observer -class MapNavigation extends React.Component { +class MapNavigationBase extends React.Component { static displayName = "MapNavigation"; private navigationRef = React.createRef(); private readonly resizeListener: () => any; @@ -328,27 +325,6 @@ class MapNavigation extends React.Component { } } -export default withTranslation()( - withTheme(withControlledVisibility(MapNavigation)) +export const MapNavigation = withTranslation()( + withTheme(withControlledVisibility(MapNavigationBase)) ); - -export function filterViewerAndScreenSize( - item: IMapNavigationItem, - viewState: ViewState -) { - const currentViewer = viewState.terria.mainViewer.viewerMode; - const screenSize: ScreenSize = item.screenSize ?? "any"; - if (viewState.useSmallScreenInterface) { - return ( - (!isDefined(item.controller.viewerMode) || - item.controller.viewerMode === currentViewer) && - (screenSize === "any" || item.screenSize === "small") - ); - } else { - return ( - (!isDefined(item.controller.viewerMode) || - item.controller.viewerMode === currentViewer) && - (screenSize === "any" || item.screenSize === "medium") - ); - } -} diff --git a/lib/ReactViews/Map/MapNavigation/filterViewerAndScreenSize.ts b/lib/ReactViews/Map/MapNavigation/filterViewerAndScreenSize.ts new file mode 100644 index 00000000000..d555f60305a --- /dev/null +++ b/lib/ReactViews/Map/MapNavigation/filterViewerAndScreenSize.ts @@ -0,0 +1,25 @@ +import isDefined from "../../../Core/isDefined"; +import ViewState from "../../../ReactViewModels/ViewState"; +import { ScreenSize } from "../../../ViewModels/CompositeBar/CompositeBarModel"; +import { IMapNavigationItem } from "../../../ViewModels/MapNavigation/MapNavigationModel"; + +export function filterViewerAndScreenSize( + item: IMapNavigationItem, + viewState: ViewState +) { + const currentViewer = viewState.terria.mainViewer.viewerMode; + const screenSize: ScreenSize = item.screenSize ?? "any"; + if (viewState.useSmallScreenInterface) { + return ( + (!isDefined(item.controller.viewerMode) || + item.controller.viewerMode === currentViewer) && + (screenSize === "any" || item.screenSize === "small") + ); + } else { + return ( + (!isDefined(item.controller.viewerMode) || + item.controller.viewerMode === currentViewer) && + (screenSize === "any" || item.screenSize === "medium") + ); + } +} diff --git a/lib/ReactViews/Map/MapNavigation/index.ts b/lib/ReactViews/Map/MapNavigation/index.ts new file mode 100644 index 00000000000..0511deeab3f --- /dev/null +++ b/lib/ReactViews/Map/MapNavigation/index.ts @@ -0,0 +1,2 @@ +export { CollapsedNavigation } from "./CollapsedNavigation"; +export { MapNavigation } from "./MapNavigation"; diff --git a/lib/ReactViews/Map/Navigation/registerMapNavigations.tsx b/lib/ReactViews/Map/MapNavigation/registerMapNavigations.tsx similarity index 92% rename from lib/ReactViews/Map/Navigation/registerMapNavigations.tsx rename to lib/ReactViews/Map/MapNavigation/registerMapNavigations.tsx index 2a3a731c1e2..3c48d555e87 100644 --- a/lib/ReactViews/Map/Navigation/registerMapNavigations.tsx +++ b/lib/ReactViews/Map/MapNavigation/registerMapNavigations.tsx @@ -18,14 +18,16 @@ import { AugmentedVirtualityController, AugmentedVirtualityHoverController, AugmentedVirtualityRealign, - AugmentedVirtualityRealignController -} from "./Items/AugmentedVirtualityTool"; -import CloseToolButton from "./Items/CloseToolButton"; -import Compass, { COMPASS_TOOL_ID } from "./Items/Compass"; -import MeasureTool from "./Items/MeasureTool"; -import MyLocation from "./Items/MyLocation"; -import { ToggleSplitterController } from "./Items/ToggleSplitterTool"; -import ZoomControl, { ZOOM_CONTROL_ID } from "./Items/ZoomControl"; + AugmentedVirtualityRealignController, + CloseToolButton, + Compass, + COMPASS_TOOL_ID, + MeasureTool, + MyLocation, + ToggleSplitterController, + ZoomControl, + ZOOM_CONTROL_ID +} from "./Items"; export const CLOSE_TOOL_ID = "close-tool"; @@ -135,7 +137,7 @@ export const registerMapNavigations = (viewState: ViewState) => { location: "TOP", screenSize: undefined, controller: closeToolButtonController, - render: , + render: , order: 7 }); closeToolButtonController.setVisible(false); diff --git a/lib/ReactViews/Map/HelpButton/HelpButton.tsx b/lib/ReactViews/Map/MenuBar/HelpButton/HelpButton.tsx similarity index 86% rename from lib/ReactViews/Map/HelpButton/HelpButton.tsx rename to lib/ReactViews/Map/MenuBar/HelpButton/HelpButton.tsx index 90b73e41868..91a1fbeafce 100644 --- a/lib/ReactViews/Map/HelpButton/HelpButton.tsx +++ b/lib/ReactViews/Map/MenuBar/HelpButton/HelpButton.tsx @@ -1,10 +1,10 @@ import React from "react"; import { useTranslation } from "react-i18next"; -import ViewState from "../../../ReactViewModels/ViewState"; -import Icon from "../../../Styled/Icon"; -import Text from "../../../Styled/Text"; -import Prompt from "../../Generic/Prompt"; +import ViewState from "../../../../ReactViewModels/ViewState"; +import Icon from "../../../../Styled/Icon"; +import Text from "../../../../Styled/Text"; +import Prompt from "../../../Generic/Prompt"; import Styles from "./help-button.scss"; import { runInAction } from "mobx"; diff --git a/lib/ReactViews/Map/MenuBar/HelpButton/help-button.scss b/lib/ReactViews/Map/MenuBar/HelpButton/help-button.scss new file mode 100644 index 00000000000..fa774176e12 --- /dev/null +++ b/lib/ReactViews/Map/MenuBar/HelpButton/help-button.scss @@ -0,0 +1,4 @@ +.helpBtn { + composes: btn from "../../../../Sass/common/_buttons.scss"; + composes: btn--map from "../../../../Sass/common/_buttons.scss"; +} diff --git a/lib/ReactViews/Map/HelpButton/help-button.scss.d.ts b/lib/ReactViews/Map/MenuBar/HelpButton/help-button.scss.d.ts similarity index 100% rename from lib/ReactViews/Map/HelpButton/help-button.scss.d.ts rename to lib/ReactViews/Map/MenuBar/HelpButton/help-button.scss.d.ts diff --git a/lib/ReactViews/Map/MenuBar.jsx b/lib/ReactViews/Map/MenuBar/MenuBar.jsx similarity index 91% rename from lib/ReactViews/Map/MenuBar.jsx rename to lib/ReactViews/Map/MenuBar/MenuBar.jsx index 601021c5d8e..18bdef81b51 100644 --- a/lib/ReactViews/Map/MenuBar.jsx +++ b/lib/ReactViews/Map/MenuBar/MenuBar.jsx @@ -3,17 +3,17 @@ import styled from "styled-components"; import PropTypes from "prop-types"; import classNames from "classnames"; -import SettingPanel from "./Panels/SettingPanel"; -import SharePanel from "./Panels/SharePanel/SharePanel"; -import ToolsPanel from "./Panels/ToolsPanel/ToolsPanel"; +import SettingPanel from "../Panels/SettingPanel"; +import SharePanel from "../Panels/SharePanel/SharePanel"; +import ToolsPanel from "../Panels/ToolsPanel/ToolsPanel"; import StoryButton from "./StoryButton/StoryButton"; -import LangPanel from "./Panels/LangPanel/LangPanel"; +import LangPanel from "../Panels/LangPanel/LangPanel"; import Styles from "./menu-bar.scss"; import { runInAction } from "mobx"; import { observer } from "mobx-react"; -import withControlledVisibility from "../../ReactViews/HOCs/withControlledVisibility"; +import withControlledVisibility from "../../HOCs/withControlledVisibility"; import HelpButton from "./HelpButton/HelpButton"; const StyledMenuBar = styled.div` @@ -117,7 +117,6 @@ MenuBar.displayName = "MenuBar"; MenuBar.propTypes = { terria: PropTypes.object, viewState: PropTypes.object.isRequired, - allBaseMaps: PropTypes.array, // Not implemented yet animationDuration: PropTypes.number, menuItems: PropTypes.arrayOf(PropTypes.element), menuLeftItems: PropTypes.arrayOf(PropTypes.element) diff --git a/lib/ReactViews/Map/StoryButton/StoryButton.tsx b/lib/ReactViews/Map/MenuBar/StoryButton/StoryButton.tsx similarity index 88% rename from lib/ReactViews/Map/StoryButton/StoryButton.tsx rename to lib/ReactViews/Map/MenuBar/StoryButton/StoryButton.tsx index 2f9e2713f80..3be439d76b5 100644 --- a/lib/ReactViews/Map/StoryButton/StoryButton.tsx +++ b/lib/ReactViews/Map/MenuBar/StoryButton/StoryButton.tsx @@ -2,13 +2,13 @@ import React, { Ref } from "react"; import { Trans, useTranslation } from "react-i18next"; import { DefaultTheme } from "styled-components"; -import triggerResize from "../../../Core/triggerResize"; -import Terria from "../../../Models/Terria"; -import ViewState from "../../../ReactViewModels/ViewState"; -import Icon from "../../../Styled/Icon"; -import Text from "../../../Styled/Text"; -import Prompt from "../../Generic/Prompt"; -import { useRefForTerria } from "../../Hooks/useRefForTerria"; +import triggerResize from "../../../../Core/triggerResize"; +import Terria from "../../../../Models/Terria"; +import ViewState from "../../../../ReactViewModels/ViewState"; +import Icon from "../../../../Styled/Icon"; +import Text from "../../../../Styled/Text"; +import Prompt from "../../../Generic/Prompt"; +import { useRefForTerria } from "../../../Hooks/useRefForTerria"; import Styles from "./story-button.scss"; diff --git a/lib/ReactViews/Map/MenuBar/StoryButton/story-button.scss b/lib/ReactViews/Map/MenuBar/StoryButton/story-button.scss new file mode 100644 index 00000000000..b3aa3dad359 --- /dev/null +++ b/lib/ReactViews/Map/MenuBar/StoryButton/story-button.scss @@ -0,0 +1,13 @@ +@import "~terriajs-variables"; + +.storyBtn { + composes: btn from "../../../../Sass/common/_buttons.scss"; + composes: btn--map from "../../../../Sass/common/_buttons.scss"; + + &:hover, + &:focus { + svg { + fill: #ffffff; + } + } +} diff --git a/lib/ReactViews/Map/StoryButton/story-button.scss.d.ts b/lib/ReactViews/Map/MenuBar/StoryButton/story-button.scss.d.ts similarity index 100% rename from lib/ReactViews/Map/StoryButton/story-button.scss.d.ts rename to lib/ReactViews/Map/MenuBar/StoryButton/story-button.scss.d.ts diff --git a/lib/ReactViews/Map/menu-bar.scss b/lib/ReactViews/Map/MenuBar/menu-bar.scss similarity index 83% rename from lib/ReactViews/Map/menu-bar.scss rename to lib/ReactViews/Map/MenuBar/menu-bar.scss index 97656d4e0df..0508b8c6abc 100644 --- a/lib/ReactViews/Map/menu-bar.scss +++ b/lib/ReactViews/Map/MenuBar/menu-bar.scss @@ -22,9 +22,9 @@ margin-left: 165px; } .menu { - composes: list-reset from "../../Sass/common/_base.scss"; - composes: clearfix from "../../Sass/common/_base.scss"; - composes: sm-show from "../../Sass/common/_base.scss"; + composes: list-reset from "../../../Sass/common/_base.scss"; + composes: clearfix from "../../../Sass/common/_base.scss"; + composes: sm-show from "../../../Sass/common/_base.scss"; margin: 0 $padding-small $padding-small $padding-small; @@ -75,11 +75,11 @@ } .flex { - composes: flex from "../../Sass/common/_base.scss"; + composes: flex from "../../../Sass/common/_base.scss"; } .langBtn { - composes: btn from "../../Sass/common/_buttons.scss"; - composes: btn--map from "../../Sass/common/_buttons.scss"; + composes: btn from "../../../Sass/common/_buttons.scss"; + composes: btn--map from "../../../Sass/common/_buttons.scss"; text-transform: uppercase; } diff --git a/lib/ReactViews/Map/menu-bar.scss.d.ts b/lib/ReactViews/Map/MenuBar/menu-bar.scss.d.ts similarity index 100% rename from lib/ReactViews/Map/menu-bar.scss.d.ts rename to lib/ReactViews/Map/MenuBar/menu-bar.scss.d.ts diff --git a/lib/ReactViews/Map/Navigation/FullScreenButton.jsx b/lib/ReactViews/Map/Navigation/FullScreenButton.jsx deleted file mode 100644 index 36b8f1ec15a..00000000000 --- a/lib/ReactViews/Map/Navigation/FullScreenButton.jsx +++ /dev/null @@ -1,60 +0,0 @@ -"use strict"; -const React = require("react"); -const createReactClass = require("create-react-class"); -const PropTypes = require("prop-types"); -import Styles from "./full_screen_button.scss"; -import classNames from "classnames"; -import Icon from "../../../Styled/Icon"; - -// The button to make the map full screen and hide the workbench. -const FullScreenButton = createReactClass({ - displayName: "FullScreenButton", - - propTypes: { - terria: PropTypes.object, - viewState: PropTypes.object.isRequired, - animationDuration: PropTypes.number // Defaults to 1 millisecond. - }, - - getInitialState() { - return { - isActive: false - }; - }, - - toggleFullScreen() { - this.props.viewState.setIsMapFullScreen( - !this.props.viewState.isMapFullScreen - ); - }, - - renderButtonText() { - if (this.props.viewState.isMapFullScreen) { - return Show Workbench; - } else { - return ; - } - }, - - render() { - const btnClassName = classNames(Styles.btn, { - [Styles.isActive]: this.props.viewState.isMapFullScreen - }); - const btnTitle = this.props.viewState.isMapFullScreen - ? "Show workbench" - : "Hide workbench"; - return ( -
- -
- ); - } -}); -module.exports = FullScreenButton; diff --git a/lib/ReactViews/Map/Panels/HelpPanel/HelpPanel.jsx b/lib/ReactViews/Map/Panels/HelpPanel/HelpPanel.jsx index a4ce63e81d9..bb774a57d4f 100644 --- a/lib/ReactViews/Map/Panels/HelpPanel/HelpPanel.jsx +++ b/lib/ReactViews/Map/Panels/HelpPanel/HelpPanel.jsx @@ -14,7 +14,7 @@ import Icon, { StyledIcon } from "../../../../Styled/Icon"; import Spacing from "../../../../Styled/Spacing"; import Text from "../../../../Styled/Text"; import parseCustomMarkdownToReact from "../../../Custom/parseCustomMarkdownToReact"; -import { withViewState } from "../../../StandardUserInterface/ViewStateContext"; +import { withViewState } from "../../../Context"; import HelpPanelItem from "./HelpPanelItem"; export const HELP_PANEL_ID = "help"; diff --git a/lib/ReactViews/Map/Panels/HelpPanel/HelpPanelItem.jsx b/lib/ReactViews/Map/Panels/HelpPanel/HelpPanelItem.jsx index 42bd18c6841..d4086330207 100644 --- a/lib/ReactViews/Map/Panels/HelpPanel/HelpPanelItem.jsx +++ b/lib/ReactViews/Map/Panels/HelpPanel/HelpPanelItem.jsx @@ -10,7 +10,7 @@ import { import { isJsonString } from "../../../../Core/Json"; import Icon, { StyledIcon } from "../../../../Styled/Icon"; import Text from "../../../../Styled/Text"; -import { applyTranslationIfExists } from "./../../../../Language/languageHelpers"; +import { applyTranslationIfExists } from "../../../../Language/languageHelpers"; import HelpVideoPanel from "./HelpVideoPanel"; @observer diff --git a/lib/ReactViews/Map/Panels/LangPanel/LangPanel.tsx b/lib/ReactViews/Map/Panels/LangPanel/LangPanel.tsx index f05b81a990d..2ad49bc15b8 100644 --- a/lib/ReactViews/Map/Panels/LangPanel/LangPanel.tsx +++ b/lib/ReactViews/Map/Panels/LangPanel/LangPanel.tsx @@ -6,7 +6,7 @@ import { RawButton } from "../../../../Styled/Button"; import Icon from "../../../../Styled/Icon"; import Ul, { Li } from "../../../../Styled/List"; import MenuPanel from "../../../StandardUserInterface/customizable/MenuPanel"; -import Styles from "../../menu-bar.scss"; +import Styles from "../../MenuBar/menu-bar.scss"; const stripLangLocale = (lang: string = ""): string => lang.split("-")[0]; diff --git a/lib/ReactViews/Map/Panels/SharePanel/Print/PrintView.tsx b/lib/ReactViews/Map/Panels/SharePanel/Print/PrintView.tsx index 3beb8fa44d5..4507a17913e 100644 --- a/lib/ReactViews/Map/Panels/SharePanel/Print/PrintView.tsx +++ b/lib/ReactViews/Map/Panels/SharePanel/Print/PrintView.tsx @@ -2,9 +2,9 @@ import DOMPurify from "dompurify"; import React, { useEffect, useRef, useState } from "react"; import ReactDOM from "react-dom"; import { StyleSheetManager, ThemeProvider } from "styled-components"; -import { terriaTheme } from "../../../../StandardUserInterface/StandardTheme"; -import { useViewState } from "../../../../StandardUserInterface/ViewStateContext"; -import DistanceLegend from "../../../Legend/DistanceLegend"; +import { terriaTheme } from "../../../../StandardUserInterface"; +import { useViewState } from "../../../../Context"; +import { DistanceLegend } from "../../../BottomBar/DistanceLegend"; import { buildShareLink, buildShortShareLink, @@ -72,10 +72,19 @@ const styles = ` padding: 5px; } + .tjs-legend__distanceLegend > label { + color: black; + } + + .tjs-legend__distanceLegend:hover { + background: #fff; + } + .tjs-legend__bar { border-bottom: 3px solid black; border-right: 3px solid black; border-left: 3px solid black; + margin: 0 auto; } body { @@ -174,7 +183,6 @@ const PrintView = (props: Props) => { {screenshot ? ( 0 ? rawPercentage : 100 - ); - - this.setState({ - percentage: sanitisedPercentage - }); - }, - - setMode(loading) { - this.setState({ loading: loading }); - }, - - componentWillUnmount() { - this.eventHelper.removeAll(); - }, - - /** - * Progress bar is influced by two loading states: - * The base globe where the progress bar shows actual progress, - * Sources where load progress is indeterminate including 3DTilesets where the progress bar is animated. - */ - render() { - const determinateProgress = this.state.percentage + "%"; - const indeterminateStillLoading = this.state.loading; - const allComplete = this.state.percentage === 100 && !this.state.loading; - - // use the baseMapContrastColor to ensure progress bar is visible on light backgrounds. If contrast color is white, use it. If its black, use the primary color of the current theme. - const backgroundColor = - this.props.viewState.terria.baseMapContrastColor === "#ffffff" - ? "#ffffff" - : this.props.theme.colorPrimary; - - return ( -
- ); - } - }) -); - -export default withViewState(withTheme(ProgressBar)); diff --git a/lib/ReactViews/Map/ProgressBar.tsx b/lib/ReactViews/Map/ProgressBar.tsx new file mode 100644 index 00000000000..a35f3f30a5f --- /dev/null +++ b/lib/ReactViews/Map/ProgressBar.tsx @@ -0,0 +1,90 @@ +import React, { VFC, useCallback, useEffect, useMemo, useState } from "react"; +import styled, { keyframes, useTheme } from "styled-components"; +import EventHelper from "terriajs-cesium/Source/Core/EventHelper"; +import { useViewState } from "../Context"; + +export const ProgressBar: VFC = () => { + const [loadPercentage, setLoadPercentage] = useState(0); + const [indeterminateLoading, setIndeterminateLoading] = useState(); + + const theme = useTheme(); + const { terria } = useViewState(); + + const setProgress = useCallback((remaining: number, max: number) => { + const rawPercentage = (1 - remaining / max) * 100; + const sanitisedPercentage = Math.floor(remaining > 0 ? rawPercentage : 100); + setLoadPercentage(sanitisedPercentage); + }, []); + + const setMode = (mode: any) => { + setIndeterminateLoading(mode); + }; + + useEffect(() => { + const eventHelper = new EventHelper(); + + eventHelper.add(terria.tileLoadProgressEvent, setProgress); + + eventHelper.add(terria.indeterminateTileLoadProgressEvent, setMode); + + return () => { + eventHelper.removeAll(); + }; + }, []); + + const backgroundColor = useMemo( + () => + terria.baseMapContrastColor === "#ffffff" + ? "#ffffff" + : theme.colorPrimary, + [] + ); + + const allComplete = loadPercentage === 100 && !indeterminateLoading; + + return ( + + ); +}; + +interface IStyledProgressBarProps { + loadPercentage: string; + complete: boolean; + indeterminate: boolean; + backgroundColor: string; +} + +const StyledProgressBar = styled.div` + height: 5px; + overflow: hidden; + transition: opacity 200ms linear, width 200ms linear, visibility 400ms linear; + background-color: ${props => props.backgroundColor}; + width: ${props => props.loadPercentage}; + + ${props => props.complete && `visibility: hidden;`} + + ${props => + props.indeterminate && + ` + width: 100%; + animation: ${indeterminateAnimation} 1.2s infinite linear; + transform-origin: 0% 50%; + `} +`; + +const indeterminateAnimation = keyframes` + 0% { + transform: translateX(0) scaleX(0); + } + 40% { + transform: translateX(0) scaleX(0.4); + } + 100% { + transform: translateX(100%) scaleX(0.5); + } +}`; diff --git a/lib/ReactViews/Map/Splitter.jsx b/lib/ReactViews/Map/Splitter.jsx deleted file mode 100644 index caf89e9b71d..00000000000 --- a/lib/ReactViews/Map/Splitter.jsx +++ /dev/null @@ -1,230 +0,0 @@ -import React from "react"; -import createReactClass from "create-react-class"; -import PropTypes from "prop-types"; -import { withTranslation } from "react-i18next"; -import { GLYPHS, StyledIcon } from "../../Styled/Icon"; -import Styles from "./splitter.scss"; -import { observer } from "mobx-react"; -import { runInAction } from "mobx"; - -// Feature detect support for passive: true in event subscriptions. -// See https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Safely_detecting_option_support -let passiveSupported = false; -try { - const options = Object.defineProperty({}, "passive", { - get: function() { - passiveSupported = true; - return true; - } - }); - - window.addEventListener("test", null, options); - window.removeEventListener("test", null, options); -} catch (err) {} - -const notPassive = passiveSupported ? { passive: false } : false; - -const Splitter = observer( - createReactClass({ - displayName: "Splitter", - - propTypes: { - terria: PropTypes.object.isRequired, - viewState: PropTypes.object.isRequired, - thumbSize: PropTypes.number, - padding: PropTypes.number, - t: PropTypes.func.isRequired - }, - - getDefaultProps() { - return { - thumbSize: 42, - padding: 0 - }; - }, - - componentDidMount() { - const that = this; - window.addEventListener("resize", function() { - that.forceRefresh(); - }); - }, - - componentWillUnmount() { - this.unsubscribe(); - }, - - forceRefresh() { - const smallChange = - this.props.terria.splitPosition < 0.5 ? 0.0001 : -0.0001; // Make sure never <0 or >1. - runInAction(() => { - this.props.terria.splitPosition += smallChange; - }); - }, - - startDrag(event) { - const viewer = this.props.terria.currentViewer; - viewer.pauseMapInteraction(); - - // While dragging is in progress, subscribe to document-level movement and up events. - document.addEventListener("mousemove", this.drag, notPassive); - document.addEventListener("touchmove", this.drag, notPassive); - document.addEventListener("mouseup", this.stopDrag, notPassive); - document.addEventListener("touchend", this.stopDrag, notPassive); - - event.preventDefault(); - event.stopPropagation(); - }, - - drag(event) { - let clientX = event.clientX; - let clientY = event.clientY; - if (event.targetTouches && event.targetTouches.length > 0) { - clientX = event.targetTouches.item(0).clientX; - clientY = event.targetTouches.item(0).clientY; - } - - const viewer = this.props.terria.mainViewer.currentViewer; - const container = viewer.getContainer(); - const mapRect = container.getBoundingClientRect(); - - const that = this; - function computeSplitFraction(startBound, endBound, position) { - const difference = endBound - startBound; - const fraction = (position - startBound) / difference; - - const min = - startBound + that.props.padding + that.props.thumbSize * 0.5; - const max = endBound - that.props.padding - that.props.thumbSize * 0.5; - const minFraction = (min - startBound) / difference; - const maxFraction = (max - startBound) / difference; - - return Math.min(maxFraction, Math.max(minFraction, fraction)); - } - let splitFractionX = computeSplitFraction( - mapRect.left, - mapRect.right, - clientX - ); - let splitFractionY = computeSplitFraction( - mapRect.top, - mapRect.bottom, - clientY - ); - - // We compute the maximum and minium windows bounds as a percentage so that we can always apply the bounds - // restriction as a percentage for consistency (we currently use absolute values for X and percentage values for - // Y, but always apply the constraint as a percentage). - // We use absolute pixel values for horizontal restriction because of the fixed UI elements which occupy an - // absolute amount of screen relestate and 100 px seems like a fine amount for the current UI. - const minX = computeSplitFraction( - mapRect.left, - mapRect.right, - mapRect.left + 100 - ); - const maxX = computeSplitFraction( - mapRect.left, - mapRect.right, - mapRect.right - 100 - ); - // Resctrict to within +/-30% of the center vertically (so we don't run into the top and bottom UI elements). - const minY = 0.2; - const maxY = 0.8; - - splitFractionX = Math.min(maxX, Math.max(minX, splitFractionX)); - splitFractionY = Math.min(maxY, Math.max(minY, splitFractionY)); - - runInAction(() => { - this.props.terria.splitPosition = splitFractionX; - this.props.terria.splitPositionVertical = splitFractionY; - }); - - event.preventDefault(); - event.stopPropagation(); - }, - - stopDrag(event) { - this.unsubscribe(); - - const viewer = this.props.terria.currentViewer; - // Ensure splitter stays in sync with map - this.props.viewState.triggerResizeEvent(); - - viewer.resumeMapInteraction(); - - event.preventDefault(); - event.stopPropagation(); - }, - - unsubscribe() { - document.removeEventListener("mousemove", this.drag, notPassive); - document.removeEventListener("touchmove", this.drag, notPassive); - document.removeEventListener("mouseup", this.stopDrag, notPassive); - document.removeEventListener("touchend", this.stopDrag, notPassive); - window.removeEventListener("resize", this.forceRefresh); - }, - - getPosition() { - const canvasWidth = this.props.terria.currentViewer.getContainer() - .clientWidth; - const canvasHeight = this.props.terria.currentViewer.getContainer() - .clientHeight; - return { - x: this.props.terria.splitPosition * canvasWidth, - y: this.props.terria.splitPositionVertical * canvasHeight - }; - }, - - render() { - if ( - !this.props.terria.showSplitter || - !this.props.terria.currentViewer.canShowSplitter || - !this.props.terria.currentViewer.getContainer() - ) { - return null; - } - - const thumbWidth = this.props.thumbSize; - const position = this.getPosition(); - - const dividerStyle = { - left: position.x + "px", - backgroundColor: this.props.terria.baseMapContrastColor - }; - - const thumbStyle = { - left: position.x + "px", - top: position.y + "px", - width: thumbWidth + "px", - height: thumbWidth + "px", - marginLeft: "-" + thumbWidth * 0.5 + "px", - marginTop: "-" + thumbWidth * 0.5 + "px", - lineHeight: thumbWidth - 2 + "px", - borderRadius: thumbWidth * 0.5 + "px", - fontSize: thumbWidth - 12 + "px" - }; - - const { t } = this.props; - - return ( -
-
-
-
- -
- ); - } - }) -); - -module.exports = withTranslation()(Splitter); diff --git a/lib/ReactViews/Map/StoryButton/story-button.scss b/lib/ReactViews/Map/StoryButton/story-button.scss deleted file mode 100644 index 51c17ff0a88..00000000000 --- a/lib/ReactViews/Map/StoryButton/story-button.scss +++ /dev/null @@ -1,13 +0,0 @@ -@import "~terriajs-variables"; - -.storyBtn { - composes: btn from "../../../Sass/common/_buttons.scss"; - composes: btn--map from "../../../Sass/common/_buttons.scss"; - - &:hover, - &:focus { - svg { - fill: #ffffff; - } - } -} diff --git a/lib/ReactViews/Map/TerriaViewerWrapper.jsx b/lib/ReactViews/Map/TerriaViewerWrapper.jsx deleted file mode 100644 index 06888dab80d..00000000000 --- a/lib/ReactViews/Map/TerriaViewerWrapper.jsx +++ /dev/null @@ -1,57 +0,0 @@ -import React from "react"; -import PropTypes from "prop-types"; -import { observer } from "mobx-react"; - -import Styles from "./terria-viewer-wrapper.scss"; - -import Splitter from "./Splitter"; -// eslint-disable-next-line no-unused-vars -import TerriaViewer from "../../ViewModels/TerriaViewer"; - -/** - * @typedef {object} Props - * @prop {Terria} terria - * @prop {ViewState} viewState - * - * @extends {React.Component} - */ -@observer -class TerriaViewerWrapper extends React.Component { - static propTypes = { - terria: PropTypes.object.isRequired, - viewState: PropTypes.object.isRequired - }; - - /** - * @argument {HTMLDivElement} container - */ - containerRef = container => { - this.props.terria.mainViewer.attached && - this.props.terria.mainViewer.detach(); - if (container !== null) { - this.props.terria.mainViewer.attach(container); - } - }; - - componentWillUnmount() { - this.props.terria.mainViewer.attached && - this.props.terria.mainViewer.detach(); - } - - render() { - return ( - - ); - } -} -module.exports = TerriaViewerWrapper; diff --git a/lib/ReactViews/Map/TerriaViewerWrapper/Splitter/Splitter.tsx b/lib/ReactViews/Map/TerriaViewerWrapper/Splitter/Splitter.tsx new file mode 100644 index 00000000000..2865d8a4543 --- /dev/null +++ b/lib/ReactViews/Map/TerriaViewerWrapper/Splitter/Splitter.tsx @@ -0,0 +1,102 @@ +import { runInAction } from "mobx"; +import { observer } from "mobx-react"; +import React, { FC, useCallback, useEffect } from "react"; +import { useTranslation } from "react-i18next"; +import { useTheme } from "styled-components"; +import Terria from "../../../../Models/Terria"; +import { GLYPHS, StyledIcon } from "../../../../Styled/Icon"; +import { useViewState } from "../../../Context"; +import { useDragHook } from "./dragHook"; + +interface ISplitterProps { + thumbSize?: number; + padding?: number; +} + +export const Splitter: FC = observer( + ({ thumbSize = 42, padding = 0 }) => { + const viewState = useViewState(); + const theme = useTheme(); + const { t } = useTranslation(); + + const { startDrag, dragUnsubscribe } = useDragHook( + viewState, + padding, + thumbSize + ); + + const onResize = useCallback(() => { + const smallChange = + viewState.terria.splitPosition < 0.5 ? 0.0001 : -0.0001; // Make sure never <0 or >1. + runInAction(() => { + viewState.terria.splitPosition += smallChange; + }); + }, [viewState]); + + useEffect(() => { + window.addEventListener("resize", onResize); + return () => { + dragUnsubscribe(); + window.removeEventListener("resize", onResize); + }; + }, [onResize, dragUnsubscribe]); + + if ( + !viewState.terria.showSplitter || + !viewState.terria.currentViewer.canShowSplitter || + !viewState.terria.currentViewer.getContainer() + ) { + return null; + } + + const position = getPosition(viewState.terria); + + return ( +
+
+
+
+ +
+ ); + } +); + +const getPosition = (terria: Terria) => { + const canvasWidth = terria.currentViewer.getContainer()?.clientWidth || 0; + const canvasHeight = terria.currentViewer.getContainer()?.clientHeight || 0; + return { + x: terria.splitPosition * canvasWidth, + y: terria.splitPositionVertical * canvasHeight + }; +}; diff --git a/lib/ReactViews/Map/TerriaViewerWrapper/Splitter/dragHook.ts b/lib/ReactViews/Map/TerriaViewerWrapper/Splitter/dragHook.ts new file mode 100644 index 00000000000..69ee2a8a607 --- /dev/null +++ b/lib/ReactViews/Map/TerriaViewerWrapper/Splitter/dragHook.ts @@ -0,0 +1,166 @@ +import { runInAction } from "mobx"; +import { + MouseEvent as ReactMouseEvent, + TouchEvent as ReactTouchEvent, + useCallback +} from "react"; +import ViewState from "../../../../ReactViewModels/ViewState"; + +// Feature detect support for passive: true in event subscriptions. +// See https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Safely_detecting_option_support +let passiveSupported = false; +try { + const options = Object.defineProperty({}, "passive", { + get: function() { + passiveSupported = true; + return true; + } + }); + + const callback = () => { + return null; + }; + + window.addEventListener("test", callback, options); + window.removeEventListener("test", callback, options); +} catch (err) {} + +const notPassive = passiveSupported ? { passive: false } : false; + +export const useDragHook = ( + viewState: ViewState, + padding: number, + thumbSize: number +) => { + const drag = useCallback( + (e: MouseEvent | TouchEvent) => { + let clientX: number | undefined = undefined; + let clientY: number | undefined = undefined; + if (e instanceof MouseEvent) { + clientX = e.clientX; + clientY = e.clientY; + } else { + if (e.targetTouches && e.targetTouches.length > 0) { + clientX = e.targetTouches.item(0)?.clientX; + clientY = e.targetTouches.item(0)?.clientY; + } + } + if (!clientX || !clientY) return; + + const viewer = viewState.terria.mainViewer.currentViewer; + const container = viewer.getContainer(); + const mapRect = container?.getBoundingClientRect(); + if (!mapRect) return; + + let splitFractionX = computeSplitFraction( + mapRect.left, + mapRect.right, + clientX, + padding, + thumbSize + ); + let splitFractionY = computeSplitFraction( + mapRect.top, + mapRect.bottom, + clientY, + padding, + thumbSize + ); + + // We compute the maximum and minium windows bounds as a percentage so that we can always apply the bounds + // restriction as a percentage for consistency (we currently use absolute values for X and percentage values for + // Y, but always apply the constraint as a percentage). + // We use absolute pixel values for horizontal restriction because of the fixed UI elements which occupy an + // absolute amount of screen relestate and 100 px seems like a fine amount for the current UI. + const minX = computeSplitFraction( + mapRect.left, + mapRect.right, + mapRect.left + 100, + padding, + thumbSize + ); + const maxX = computeSplitFraction( + mapRect.left, + mapRect.right, + mapRect.right - 100, + padding, + thumbSize + ); + // Resctrict to within +/-30% of the center vertically (so we don't run into the top and bottom UI elements). + const minY = 0.2; + const maxY = 0.8; + + splitFractionX = Math.min(maxX, Math.max(minX, splitFractionX)); + splitFractionY = Math.min(maxY, Math.max(minY, splitFractionY)); + + runInAction(() => { + viewState.terria.splitPosition = splitFractionX; + viewState.terria.splitPositionVertical = splitFractionY; + }); + + e.preventDefault(); + e.stopPropagation(); + }, + [viewState] + ); + + const stopDrag = useCallback( + (e: Event) => { + dragUnsubscribe(); + + const viewer = viewState.terria.currentViewer; + // Ensure splitter stays in sync with map + viewState.triggerResizeEvent(); + + viewer.resumeMapInteraction(); + + e.preventDefault(); + e.stopPropagation(); + }, + [viewState] + ); + + const startDrag = useCallback( + (e: ReactMouseEvent | ReactTouchEvent | undefined) => { + const viewer = viewState.terria.currentViewer; + viewer.pauseMapInteraction(); + + // While dragging is in progress, subscribe to document-level movement and up events. + document.addEventListener("mousemove", drag, notPassive); + document.addEventListener("touchmove", drag, notPassive); + document.addEventListener("mouseup", stopDrag, notPassive); + document.addEventListener("touchend", stopDrag, notPassive); + + e?.preventDefault(); + e?.stopPropagation(); + }, + [drag, stopDrag, viewState] + ); + + const dragUnsubscribe = useCallback(() => { + document.removeEventListener("mousemove", drag, notPassive as never); + document.removeEventListener("touchmove", drag, notPassive as never); + document.removeEventListener("mouseup", stopDrag, notPassive as never); + document.removeEventListener("touchend", stopDrag, notPassive as never); + }, [drag, stopDrag]); + + return { startDrag, dragUnsubscribe }; +}; + +function computeSplitFraction( + startBound: number, + endBound: number, + position: number, + padding: number, + thumbSize: number +) { + const difference = endBound - startBound; + const fraction = (position - startBound) / difference; + + const min = startBound + padding + thumbSize * 0.5; + const max = endBound - padding - thumbSize * 0.5; + const minFraction = (min - startBound) / difference; + const maxFraction = (max - startBound) / difference; + + return Math.min(maxFraction, Math.max(minFraction, fraction)); +} diff --git a/lib/ReactViews/Map/TerriaViewerWrapper/TerriaViewerWrapper.tsx b/lib/ReactViews/Map/TerriaViewerWrapper/TerriaViewerWrapper.tsx new file mode 100644 index 00000000000..00ad97196fd --- /dev/null +++ b/lib/ReactViews/Map/TerriaViewerWrapper/TerriaViewerWrapper.tsx @@ -0,0 +1,84 @@ +import React, { FC, useEffect, useRef } from "react"; + +import { Splitter } from "./Splitter/Splitter"; +import { useViewState } from "../../Context"; +import styled from "styled-components"; + +export const TerriaViewerWrapper: FC = () => { + const viewState = useViewState(); + const containerRef = useRef(null); + + useEffect(() => { + if (viewState.terria.mainViewer.attached) { + viewState.terria.mainViewer.detach(); + } + if (containerRef.current) { + viewState.terria.mainViewer.attach(containerRef.current); + } + + return () => { + viewState.terria.mainViewer.detach(); + }; + }, [viewState]); + + return ( + + + Loading the map, please wait... + + +
+ + ); +}; + +const TerrriaViewerContainer = styled.aside` + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; +`; + +const StyledMapPlaceholder = styled.div` + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; + color: black; + text-align: center; + width: 100%; + height: 25%; + margin: auto; + @media (min-width: ${p => p.theme.sm}px) { + color: white; + } +`; diff --git a/lib/ReactViews/Map/TerriaViewerWrapper/index.ts b/lib/ReactViews/Map/TerriaViewerWrapper/index.ts new file mode 100644 index 00000000000..fb3377a1c87 --- /dev/null +++ b/lib/ReactViews/Map/TerriaViewerWrapper/index.ts @@ -0,0 +1 @@ +export { TerriaViewerWrapper } from "./TerriaViewerWrapper"; diff --git a/lib/ReactViews/StandardUserInterface/Toast.tsx b/lib/ReactViews/Map/Toast.tsx similarity index 100% rename from lib/ReactViews/StandardUserInterface/Toast.tsx rename to lib/ReactViews/Map/Toast.tsx diff --git a/lib/ReactViews/Map/experimental-features.scss b/lib/ReactViews/Map/experimental-features.scss deleted file mode 100644 index c9a98d01566..00000000000 --- a/lib/ReactViews/Map/experimental-features.scss +++ /dev/null @@ -1,22 +0,0 @@ -@import "~terriajs-variables"; - -.experimental-features { - position: absolute; - left: 25px; - bottom: 25px; - z-index: 1; - - @media (min-width: $sm) { - top: auto; - bottom: 100px; - } -} - -.control { - margin: 15px 0; - text-align: center; - - &:last-child { - margin-bottom: 0; - } -} diff --git a/lib/ReactViews/Map/experimental-features.scss.d.ts b/lib/ReactViews/Map/experimental-features.scss.d.ts deleted file mode 100644 index d84db085ee8..00000000000 --- a/lib/ReactViews/Map/experimental-features.scss.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -// This file is automatically generated. -// Please do not change this file! -interface CssExports { - 'control': string; - 'experimental-features': string; - 'experimentalFeatures': string; -} -declare var cssExports: CssExports; -export = cssExports; diff --git a/lib/ReactViews/Map/progress-bar.scss b/lib/ReactViews/Map/progress-bar.scss deleted file mode 100644 index 7e05acb098d..00000000000 --- a/lib/ReactViews/Map/progress-bar.scss +++ /dev/null @@ -1,31 +0,0 @@ -.progress-bar { - z-index: 1; - position: absolute; - top: 0; - left: 0; - height: 5px; - overflow: hidden; - transition: opacity 200ms linear, width 200ms linear, visibility 400ms linear; -} - -.complete { - visibility: hidden; -} - -.indeterminate-bar-animated { - width: 100%; - animation: indeterminateAnimation 1.2s infinite linear; - transform-origin: 0% 50%; -} - -@keyframes indeterminateAnimation { - 0% { - transform: translateX(0) scaleX(0); - } - 40% { - transform: translateX(0) scaleX(0.4); - } - 100% { - transform: translateX(100%) scaleX(0.5); - } -} diff --git a/lib/ReactViews/Map/progress-bar.scss.d.ts b/lib/ReactViews/Map/progress-bar.scss.d.ts deleted file mode 100644 index ae6c7a6c853..00000000000 --- a/lib/ReactViews/Map/progress-bar.scss.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -// This file is automatically generated. -// Please do not change this file! -interface CssExports { - 'complete': string; - 'indeterminate-bar-animated': string; - 'indeterminateAnimation': string; - 'indeterminateBarAnimated': string; - 'progress-bar': string; - 'progressBar': string; -} -declare var cssExports: CssExports; -export = cssExports; diff --git a/lib/ReactViews/Map/splitter.scss b/lib/ReactViews/Map/splitter.scss deleted file mode 100644 index 9849d3c22d8..00000000000 --- a/lib/ReactViews/Map/splitter.scss +++ /dev/null @@ -1,42 +0,0 @@ -@import "~terriajs-variables"; - -.divider-wrapper { - position: absolute; - width: 100%; - height: 100%; -} - -.divider { - position: absolute; - top: 0; - bottom: 0; - left: 50%; - width: 1px; - background-color: #fff; - pointer-events: none; - z-index: 999; -} - -.thumb { - position: absolute; - width: 40px; - height: 40px; - border-radius: 20px; - border: 1px solid lightgrey; - text-align: center; - line-height: 38px; - left: 50%; - top: 50%; - font-size: 28px; - font-family: monospace; - background-color: white; - color: grey; - margin-top: -20px; - margin-left: -20px; - z-index: 999; - padding: 8px; - cursor: ew-resize; - svg { - fill: #000; - } -} diff --git a/lib/ReactViews/Map/splitter.scss.d.ts b/lib/ReactViews/Map/splitter.scss.d.ts deleted file mode 100644 index e6984139b8c..00000000000 --- a/lib/ReactViews/Map/splitter.scss.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -// This file is automatically generated. -// Please do not change this file! -interface CssExports { - 'divider': string; - 'divider-wrapper': string; - 'dividerWrapper': string; - 'thumb': string; -} -declare var cssExports: CssExports; -export = cssExports; diff --git a/lib/ReactViews/Map/terria-viewer-wrapper.scss b/lib/ReactViews/Map/terria-viewer-wrapper.scss deleted file mode 100644 index 21961915fee..00000000000 --- a/lib/ReactViews/Map/terria-viewer-wrapper.scss +++ /dev/null @@ -1,57 +0,0 @@ -@import "~terriajs-variables"; -@import "../../Sass/common/mixins"; - -.container { - top: 0; - right: 0; - bottom: 0; - left: 0; - position: absolute; -} - -.cesium-container { - top: 0; - right: 0; - bottom: 0; - left: 0; - position: absolute; - cursor: auto; - - :global { - .selection-indicator { - pointer-events: none; - position: absolute; - width: 50px; - height: 50px; - } - - #terriaLogoWrapper { - display: inline-block; - } - - .cesium-widget, - .cesium-widget canvas { - position: absolute; - width: 100%; - height: 100%; - touch-action: none; - } - } -} - -.mapPlaceholder { - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - color: black; - text-align: center; - width: 100%; - height: 25%; - margin: auto; - - @media (min-width: $sm) { - color: white; - } -} diff --git a/lib/ReactViews/Map/terria-viewer-wrapper.scss.d.ts b/lib/ReactViews/Map/terria-viewer-wrapper.scss.d.ts deleted file mode 100644 index 8f5c50b26cb..00000000000 --- a/lib/ReactViews/Map/terria-viewer-wrapper.scss.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -// This file is automatically generated. -// Please do not change this file! -interface CssExports { - 'cesium-container': string; - 'cesiumContainer': string; - 'container': string; - 'mapPlaceholder': string; -} -declare var cssExports: CssExports; -export = cssExports; diff --git a/lib/ReactViews/Mobile/MobileHeader.jsx b/lib/ReactViews/Mobile/MobileHeader.jsx index b6cdc37dd35..78544200602 100644 --- a/lib/ReactViews/Mobile/MobileHeader.jsx +++ b/lib/ReactViews/Mobile/MobileHeader.jsx @@ -11,7 +11,7 @@ import { RawButton } from "../../Styled/Button"; import Icon, { StyledIcon } from "../../Styled/Icon"; import SearchBox from "../Search/SearchBox"; import Branding from "../SidePanel/Branding"; -import { withViewState } from "../StandardUserInterface/ViewStateContext"; +import { withViewState } from "../Context"; import Styles from "./mobile-header.scss"; import MobileMenu from "./MobileMenu"; import MobileModalWindow from "./MobileModalWindow"; @@ -259,7 +259,6 @@ class MobileHeader extends React.Component { menuItems={this.props.menuItems} menuLeftItems={this.props.menuLeftItems} viewState={this.props.viewState} - allBaseMaps={this.props.allBaseMaps} terria={this.props.viewState.terria} showFeedback={ !!this.props.viewState.terria.configParameters.feedbackUrl @@ -299,7 +298,6 @@ const HamburgerButton = styled(RawButton)` MobileHeader.propTypes = { viewState: PropTypes.object.isRequired, - allBaseMaps: PropTypes.array, version: PropTypes.string, menuLeftItems: PropTypes.array, menuItems: PropTypes.array, diff --git a/lib/ReactViews/Mobile/MobileMenu.jsx b/lib/ReactViews/Mobile/MobileMenu.jsx index 4181ce1a572..95a4f6b12b8 100644 --- a/lib/ReactViews/Mobile/MobileMenu.jsx +++ b/lib/ReactViews/Mobile/MobileMenu.jsx @@ -29,7 +29,6 @@ const MobileMenu = observer( showFeedback: PropTypes.bool, terria: PropTypes.object.isRequired, i18n: PropTypes.object, - allBaseMaps: PropTypes.array.isRequired, t: PropTypes.func.isRequired }, diff --git a/lib/ReactViews/Notification/MapInteractionWindow.tsx b/lib/ReactViews/Notification/MapInteractionWindow.tsx index 96881c44ef9..3fa89412f81 100644 --- a/lib/ReactViews/Notification/MapInteractionWindow.tsx +++ b/lib/ReactViews/Notification/MapInteractionWindow.tsx @@ -10,7 +10,7 @@ import isDefined from "../../Core/isDefined"; import MapInteractionMode, { UIMode } from "../../Models/MapInteractionMode"; import ViewState from "../../ReactViewModels/ViewState"; import parseCustomHtmlToReact from "../Custom/parseCustomHtmlToReact"; -import { withViewState } from "../StandardUserInterface/ViewStateContext"; +import { withViewState } from "../Context"; import Styles from "./map-interaction-window.scss"; const MapInteractionWindowWrapper = styled.div<{ isDiffTool: boolean }>` diff --git a/lib/ReactViews/Notification/Notification.tsx b/lib/ReactViews/Notification/Notification.tsx index bf33f2c27b3..4b7e597d1bc 100644 --- a/lib/ReactViews/Notification/Notification.tsx +++ b/lib/ReactViews/Notification/Notification.tsx @@ -1,7 +1,7 @@ import { observer } from "mobx-react"; import React from "react"; import triggerResize from "../../Core/triggerResize"; -import { useViewState } from "../StandardUserInterface/ViewStateContext"; +import { useViewState } from "../Context"; // Avoid type error caused by importing untyped jsx const NotificationWindow = require("./NotificationWindow").default; diff --git a/lib/ReactViews/SidePanel/Branding.tsx b/lib/ReactViews/SidePanel/Branding.tsx index 0a975a2e615..8b9d4b93a9c 100644 --- a/lib/ReactViews/SidePanel/Branding.tsx +++ b/lib/ReactViews/SidePanel/Branding.tsx @@ -4,7 +4,7 @@ import React from "react"; import isDefined from "../../Core/isDefined"; import ViewState from "../../ReactViewModels/ViewState"; import parseCustomHtmlToReact from "../Custom/parseCustomHtmlToReact"; -import { withViewState } from "../StandardUserInterface/ViewStateContext"; +import { withViewState } from "../Context"; const DEFAULT_BRANDING = ''; diff --git a/lib/ReactViews/SidePanel/FullScreenButton.jsx b/lib/ReactViews/SidePanel/FullScreenButton.jsx index 91fb9427a08..55273d9d57d 100644 --- a/lib/ReactViews/SidePanel/FullScreenButton.jsx +++ b/lib/ReactViews/SidePanel/FullScreenButton.jsx @@ -8,7 +8,7 @@ import { withTranslation } from "react-i18next"; import { Category, ViewAction } from "../../Core/AnalyticEvents/analyticEvents"; import Icon from "../../Styled/Icon"; import withControlledVisibility from "../HOCs/withControlledVisibility"; -import { withViewState } from "../StandardUserInterface/ViewStateContext"; +import { withViewState } from "../Context"; import Styles from "./full_screen_button.scss"; // The button to make the map full screen and hide the workbench. diff --git a/lib/ReactViews/SidePanel/SidePanel.tsx b/lib/ReactViews/SidePanel/SidePanel.tsx index 7e326274167..96917be2a1c 100644 --- a/lib/ReactViews/SidePanel/SidePanel.tsx +++ b/lib/ReactViews/SidePanel/SidePanel.tsx @@ -11,17 +11,21 @@ import Text from "../../Styled/Text"; import { ExplorerWindowElementName } from "../ExplorerWindow/ExplorerWindow"; import { useRefForTerria } from "../Hooks/useRefForTerria"; import SearchBoxAndResults from "../Search/SearchBoxAndResults"; -import { withViewState } from "../StandardUserInterface/ViewStateContext"; +import { withViewState } from "../Context"; import Workbench from "../Workbench/Workbench"; const BoxHelpfulHints = styled(Box)``; const ResponsiveSpacing = styled(Box)` + height: 110px; height: 110px; // Hardcoded px value, TODO: make it not hardcoded @media (max-height: 700px) { height: 3vh; } + @media (max-height: 700px) { + height: 3vh; + } `; const HelpfulHintsIcon = () => { diff --git a/lib/ReactViews/Map/ExperimentalFeatures.tsx b/lib/ReactViews/StandardUserInterface/ExperimentalFeatures.tsx similarity index 91% rename from lib/ReactViews/Map/ExperimentalFeatures.tsx rename to lib/ReactViews/StandardUserInterface/ExperimentalFeatures.tsx index 1f4beec8aed..55ec911cd8f 100644 --- a/lib/ReactViews/Map/ExperimentalFeatures.tsx +++ b/lib/ReactViews/StandardUserInterface/ExperimentalFeatures.tsx @@ -1,7 +1,7 @@ import React from "react"; import styled from "styled-components"; import ViewState from "../../ReactViewModels/ViewState"; -import { withViewState } from "../StandardUserInterface/ViewStateContext"; +import { withViewState } from "../Context"; interface IProps { viewState: ViewState; @@ -13,7 +13,6 @@ const ControlsWrapper = styled.div` left: 25px; bottom: 25px; z-index: 1; - @media (min-width: ${props => props.theme.sm}px) { top: auto; bottom: 100px; @@ -22,7 +21,6 @@ const ControlsWrapper = styled.div` const Control = styled.div` margin: 15px 0; text-align: center; - &:last-child { margin-bottom: 0; } diff --git a/lib/ReactViews/StandardUserInterface/GlobalTerriaStyles.ts b/lib/ReactViews/StandardUserInterface/GlobalTerriaStyles.ts index 18cf6d79dae..6d65b5a65db 100644 --- a/lib/ReactViews/StandardUserInterface/GlobalTerriaStyles.ts +++ b/lib/ReactViews/StandardUserInterface/GlobalTerriaStyles.ts @@ -67,4 +67,19 @@ body { button { cursor: pointer; } + +.selection-indicator { + pointer-events: none; + position: absolute; + width: 50px; + height: 50px; +} + +.cesium-widget, +.cesium-widget canvas { + position: absolute; + width: 100%; + height: 100%; + touch-action: none; +} `; diff --git a/lib/ReactViews/StandardUserInterface/MapColumn.jsx b/lib/ReactViews/StandardUserInterface/MapColumn.jsx deleted file mode 100644 index 037a2b31bbe..00000000000 --- a/lib/ReactViews/StandardUserInterface/MapColumn.jsx +++ /dev/null @@ -1,219 +0,0 @@ -import classNames from "classnames"; -import createReactClass from "create-react-class"; -import { observer } from "mobx-react"; -import PropTypes from "prop-types"; -import React from "react"; -import { withTranslation } from "react-i18next"; -import FeatureDetection from "terriajs-cesium/Source/Core/FeatureDetection"; -import BottomDock from "../BottomDock/BottomDock"; -import { MapCredits } from "../Credits"; -import Loader from "../Loader"; -import BottomLeftBar from "../Map/BottomLeftBar/BottomLeftBar"; -import DistanceLegend from "../Map/Legend/DistanceLegend"; -import LocationBar from "../Map/Legend/LocationBar"; -import MenuBar from "../Map/MenuBar"; -import MapNavigation from "../Map/Navigation/MapNavigation"; -import TerriaViewerWrapper from "../Map/TerriaViewerWrapper"; -import SlideUpFadeIn from "../Transitions/SlideUpFadeIn/SlideUpFadeIn"; -import Styles from "./map-column.scss"; -import Toast from "./Toast"; -import { withViewState } from "./ViewStateContext"; - -const chromeVersion = FeatureDetection.chromeVersion(); - -/** - * Right-hand column that contains the map, controls that sit over the map and sometimes the bottom dock containing - * the timeline and charts. - */ -const MapColumn = observer( - createReactClass({ - displayName: "MapColumn", - - propTypes: { - viewState: PropTypes.object.isRequired, - customFeedbacks: PropTypes.array.isRequired, - allBaseMaps: PropTypes.array.isRequired, - animationDuration: PropTypes.number.isRequired, - customElements: PropTypes.object.isRequired, - t: PropTypes.func.isRequired - }, - - getInitialState() { - return {}; - }, - - render() { - const { customElements } = this.props; - const { t } = this.props; - // TODO: remove? see: https://bugs.chromium.org/p/chromium/issues/detail?id=1001663 - const isAboveChrome75 = - chromeVersion && chromeVersion[0] && Number(chromeVersion[0]) > 75; - const mapCellClass = classNames(Styles.mapCell, { - [Styles.mapCellChrome]: isAboveChrome75 - }); - return ( -
-
-
- -
- - -
-
-
- -
- - - - - - - - -
- - -
-
- {/* TODO: re-implement/support custom feedbacks */} - {/* -
- -
-
*/} - - - -
{feedbackItem}
-
-
-
- - - -
- -
-
- -
-
-
-
- ); - } - }) -); - -export default withTranslation()(withViewState(MapColumn)); diff --git a/lib/ReactViews/StandardUserInterface/SidePanelContainer.tsx b/lib/ReactViews/StandardUserInterface/SidePanelContainer.tsx index 6891012b24e..6d2ba957329 100644 --- a/lib/ReactViews/StandardUserInterface/SidePanelContainer.tsx +++ b/lib/ReactViews/StandardUserInterface/SidePanelContainer.tsx @@ -1,7 +1,7 @@ import { action } from "mobx"; import styled from "styled-components"; import ViewState from "../../ReactViewModels/ViewState"; -import { withViewState } from "./ViewStateContext"; +import { withViewState } from "../Context"; type PropsType = { viewState: ViewState; diff --git a/lib/ReactViews/StandardUserInterface/StandardUserInterface.tsx b/lib/ReactViews/StandardUserInterface/StandardUserInterface.tsx index 28a04676ee6..2502918a5f9 100644 --- a/lib/ReactViews/StandardUserInterface/StandardUserInterface.tsx +++ b/lib/ReactViews/StandardUserInterface/StandardUserInterface.tsx @@ -17,12 +17,11 @@ import FeedbackForm from "../Feedback/FeedbackForm"; import { Medium, Small } from "../Generic/Responsive"; import SatelliteHelpPrompt from "../HelpScreens/SatelliteHelpPrompt"; import withFallback from "../HOCs/withFallback"; -import ExperimentalFeatures from "../Map/ExperimentalFeatures"; -import CollapsedNavigation from "../Map/Navigation/Items/OverflowNavigationItem"; +import ExperimentalFeatures from "./ExperimentalFeatures"; +import { CollapsedNavigation } from "../Map/MapNavigation"; import HelpPanel from "../Map/Panels/HelpPanel/HelpPanel"; import PrintView from "../Map/Panels/SharePanel/Print/PrintView"; -import ProgressBar from "../Map/ProgressBar"; -import TrainerBar from "../Map/TrainerBar/TrainerBar"; +import TrainerBar from "./TrainerBar/TrainerBar"; import MobileHeader from "../Mobile/MobileHeader"; import MapInteractionWindow from "../Notification/MapInteractionWindow"; import Notification from "../Notification/Notification"; @@ -35,9 +34,9 @@ import Tool from "../Tools/Tool"; import TourPortal from "../Tour/TourPortal"; import WelcomeMessage from "../WelcomeMessage/WelcomeMessage"; import SelectableDimensionWorkflow from "../Workflow/SelectableDimensionWorkflow"; -import ContextProviders from "./ContextProviders"; +import { ContextProviders } from "../Context"; import { GlobalTerriaStyles } from "./GlobalTerriaStyles"; -import MapColumn from "./MapColumn"; +import MapColumn from "../Map/MapColumn"; import processCustomElements from "./processCustomElements"; import SidePanelContainer from "./SidePanelContainer"; import Styles from "./standard-user-interface.scss"; @@ -49,13 +48,12 @@ export const animationDuration = 250; interface StandardUserInterfaceProps { terria: ViewState["terria"]; viewState: ViewState; - allBaseMaps?: any[]; themeOverrides?: Partial; minimumLargeScreenWidth?: number; version: string; } -const StandardUserInterface: React.FC = observer( +const StandardUserInterfaceBase: React.FC = observer( props => { const { t } = useTranslation(); @@ -134,7 +132,6 @@ const StandardUserInterface: React.FC = observer( ); const terria = props.terria; - const allBaseMaps = props.allBaseMaps; const showStoryBuilder = props.viewState.storyBuilderShown && @@ -177,7 +174,6 @@ const StandardUserInterface: React.FC = observer( menuItems={customElements.menu} menuLeftItems={customElements.menuLeft} version={props.version} - allBaseMaps={allBaseMaps} /> @@ -227,11 +223,9 @@ const StandardUserInterface: React.FC = observer(
-
@@ -310,4 +304,5 @@ const StandardUserInterface: React.FC = observer( } ); -export default withFallback(StandardUserInterface); +export const StandardUserInterface = withFallback(StandardUserInterfaceBase); +export default withFallback(StandardUserInterfaceBase); diff --git a/lib/ReactViews/Map/TrainerBar/TrainerBar.tsx b/lib/ReactViews/StandardUserInterface/TrainerBar/TrainerBar.tsx similarity index 99% rename from lib/ReactViews/Map/TrainerBar/TrainerBar.tsx rename to lib/ReactViews/StandardUserInterface/TrainerBar/TrainerBar.tsx index 531d31d4957..249d36c4f9f 100644 --- a/lib/ReactViews/Map/TrainerBar/TrainerBar.tsx +++ b/lib/ReactViews/StandardUserInterface/TrainerBar/TrainerBar.tsx @@ -17,10 +17,7 @@ import Select from "../../../Styled/Select"; import Spacing from "../../../Styled/Spacing"; import Text, { TextSpan } from "../../../Styled/Text"; import measureElement, { MeasureElementProps } from "../../HOCs/measureElement"; -import { - WithViewState, - withViewState -} from "../../StandardUserInterface/ViewStateContext"; +import { WithViewState, withViewState } from "../../Context"; import { applyTranslationIfExists } from "./../../../Language/languageHelpers"; const StyledHtml: any = require("../../Map/Panels/HelpPanel/StyledHtml") diff --git a/lib/ReactViews/StandardUserInterface/WorkflowPanelContainer.tsx b/lib/ReactViews/StandardUserInterface/WorkflowPanelContainer.tsx index 94ac20446ed..1bd836e38ee 100644 --- a/lib/ReactViews/StandardUserInterface/WorkflowPanelContainer.tsx +++ b/lib/ReactViews/StandardUserInterface/WorkflowPanelContainer.tsx @@ -3,7 +3,7 @@ import styled from "styled-components"; import ViewState from "../../ReactViewModels/ViewState"; import { WorkflowPanelPortalId } from "../Workflow/WorkflowPanel"; import PortalContainer from "./PortalContainer"; -import { withViewState } from "./ViewStateContext"; +import { withViewState } from "../Context"; type PropsType = { viewState: ViewState; @@ -28,10 +28,8 @@ const Container = styled.div<{ show: boolean }>` height: 100vh; width: ${p => p.theme.workflowPanelWidth}px; max-width: ${p => p.theme.workflowPanelWidth}px; - transition: all 0.25s; transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); - visibility: ${p => (p.show ? "visible" : "hidden")}; margin-left: ${p => (p.show ? "0px" : `-${p.theme.workflowPanelWidth}px`)}; opacity: ${p => (p.show ? 1 : 0)}; diff --git a/lib/ReactViews/Map/MenuButton.jsx b/lib/ReactViews/StandardUserInterface/customizable/MenuButton.jsx similarity index 95% rename from lib/ReactViews/Map/MenuButton.jsx rename to lib/ReactViews/StandardUserInterface/customizable/MenuButton.jsx index 52395c1ec2b..626bac2eacf 100644 --- a/lib/ReactViews/Map/MenuButton.jsx +++ b/lib/ReactViews/StandardUserInterface/customizable/MenuButton.jsx @@ -1,6 +1,6 @@ import React from "react"; import classNames from "classnames"; -import Icon from "../../Styled/Icon"; +import Icon from "../../../Styled/Icon"; import PropTypes from "prop-types"; import Styles from "./menu-button.scss"; diff --git a/lib/ReactViews/StandardUserInterface/customizable/MenuItem.jsx b/lib/ReactViews/StandardUserInterface/customizable/MenuItem.jsx index 9a8f1aaf321..897122345f0 100644 --- a/lib/ReactViews/StandardUserInterface/customizable/MenuItem.jsx +++ b/lib/ReactViews/StandardUserInterface/customizable/MenuItem.jsx @@ -1,4 +1,4 @@ -import MenuButton from "../../Map/MenuButton"; +import MenuButton from "./MenuButton"; import responsiveSwitch from "./ResponsiveSwitch"; import withControlledVisibility from "../../HOCs/withControlledVisibility"; import MobileMenuItem from "../../Mobile/MobileMenuItem"; diff --git a/lib/ReactViews/Map/menu-button.scss b/lib/ReactViews/StandardUserInterface/customizable/menu-button.scss similarity index 74% rename from lib/ReactViews/Map/menu-button.scss rename to lib/ReactViews/StandardUserInterface/customizable/menu-button.scss index eac534aec5d..b35fa5b3397 100644 --- a/lib/ReactViews/Map/menu-button.scss +++ b/lib/ReactViews/StandardUserInterface/customizable/menu-button.scss @@ -1,8 +1,8 @@ @import "~terriajs-variables"; .btn--about-link { - composes: btn from "../../Sass/common/_buttons.scss"; - composes: btn--map from "../../Sass/common/_buttons.scss"; + composes: btn from "../../../Sass/common/_buttons.scss"; + composes: btn--map from "../../../Sass/common/_buttons.scss"; border-radius: $radius-small; border: 0; svg { diff --git a/lib/ReactViews/Map/menu-button.scss.d.ts b/lib/ReactViews/StandardUserInterface/customizable/menu-button.scss.d.ts similarity index 100% rename from lib/ReactViews/Map/menu-button.scss.d.ts rename to lib/ReactViews/StandardUserInterface/customizable/menu-button.scss.d.ts diff --git a/lib/ReactViews/StandardUserInterface/index.ts b/lib/ReactViews/StandardUserInterface/index.ts new file mode 100644 index 00000000000..f0f63b85c00 --- /dev/null +++ b/lib/ReactViews/StandardUserInterface/index.ts @@ -0,0 +1,5 @@ +export { + StandardUserInterface, + StandardUserInterface as default +} from "./StandardUserInterface"; +export { terriaTheme } from "./StandardTheme"; diff --git a/lib/ReactViews/StandardUserInterface/map-column.scss b/lib/ReactViews/StandardUserInterface/map-column.scss deleted file mode 100644 index 93bf7fa4475..00000000000 --- a/lib/ReactViews/StandardUserInterface/map-column.scss +++ /dev/null @@ -1,99 +0,0 @@ -@import "~terriajs-variables"; -@import "../../Sass/common/mixins"; - -.map__inner { - display: table; - width: 100%; - height: 100%; - - * { - box-sizing: border-box; - } -} -.map__innerChrome { - // Chrome only :( hack until - // https://bugs.chromium.org/p/chromium/issues/detail?id=1001663 gets resolved - display: flex; - flex-flow: column; -} - -.map__row { - display: table-row; - - &:first-child { - height: 100%; - position: relative; - } -} - -.map__cell { - display: table-cell; - position: relative; - width: 100%; -} -.map__cellChrome { - // Chrome only :( hack until - // https://bugs.chromium.org/p/chromium/issues/detail?id=1001663 gets resolved - display: block; - height: 100%; -} - -@include empty-module("map-cell-map"); - -.map-wrapper { - position: absolute; - top: 0; - width: 100%; - z-index: 0; -} - -@include empty-module("feedback"); - -.location-distance { - composes: clearfix from "../../Sass/common/_base.scss"; - display: none; - @media (min-width: $sm) { - display: block; - } - position: absolute; - bottom: 2px; - right: 3px; - z-index: 1; -} - -.feedback-button-wrapper { - @media (min-width: $sm) { - bottom: 100px; - right: $padding * 2; - margin: 0; - } - - @media (max-width: $mobile) { - position: fixed; - } - position: absolute; - z-index: 0; - bottom: 25px; - right: 16px; - margin: 4px 0; -} - -.with-time-series-controls { - bottom: 58px; - - @media (max-width: $mobile) { - bottom: $mobile-bottom-timeline; - } -} - -.print-disclaimer { - display: none; -} - -@media print { - .print-disclaimer { - display: block; - width: 100%; - clear: both; - } -} diff --git a/lib/ReactViews/StandardUserInterface/map-column.scss.d.ts b/lib/ReactViews/StandardUserInterface/map-column.scss.d.ts deleted file mode 100644 index 8f9308b3b49..00000000000 --- a/lib/ReactViews/StandardUserInterface/map-column.scss.d.ts +++ /dev/null @@ -1,29 +0,0 @@ -// This file is automatically generated. -// Please do not change this file! -interface CssExports { - 'feedback': string; - 'feedback-button-wrapper': string; - 'feedbackButtonWrapper': string; - 'location-distance': string; - 'locationDistance': string; - 'map-cell-map': string; - 'map-wrapper': string; - 'mapCell': string; - 'mapCellChrome': string; - 'mapCellMap': string; - 'mapInner': string; - 'mapInnerChrome': string; - 'mapRow': string; - 'mapWrapper': string; - 'map__cell': string; - 'map__cellChrome': string; - 'map__inner': string; - 'map__innerChrome': string; - 'map__row': string; - 'print-disclaimer': string; - 'printDisclaimer': string; - 'with-time-series-controls': string; - 'withTimeSeriesControls': string; -} -declare var cssExports: CssExports; -export = cssExports; diff --git a/lib/ReactViews/Story/StoryBuilder.tsx b/lib/ReactViews/Story/StoryBuilder.tsx index e017fbd2917..289cbad1251 100644 --- a/lib/ReactViews/Story/StoryBuilder.tsx +++ b/lib/ReactViews/Story/StoryBuilder.tsx @@ -27,10 +27,7 @@ import measureElement, { MeasureElementProps } from "../HOCs/measureElement"; import VideoGuide from "../Map/Panels/HelpPanel/VideoGuide"; import { getShareData } from "../Map/Panels/SharePanel/BuildShareLink"; import SharePanel from "../Map/Panels/SharePanel/SharePanel"; -import { - WithViewState, - withViewState -} from "../StandardUserInterface/ViewStateContext"; +import { WithViewState, withViewState } from "../Context"; import Story from "./Story"; import Styles from "./story-builder.scss"; import StoryEditor from "./StoryEditor.jsx"; diff --git a/lib/ReactViews/Story/StoryPanel/StoryPanel.tsx b/lib/ReactViews/Story/StoryPanel/StoryPanel.tsx index 46aba61d34c..2eaf2430c1e 100644 --- a/lib/ReactViews/Story/StoryPanel/StoryPanel.tsx +++ b/lib/ReactViews/Story/StoryPanel/StoryPanel.tsx @@ -15,11 +15,8 @@ import TerriaError from "../../../Core/TerriaError"; import Terria from "../../../Models/Terria"; import Box from "../../../Styled/Box"; import Hr from "../../../Styled/Hr"; -import { onStoryButtonClick } from "../../Map/StoryButton/StoryButton"; -import { - WithViewState, - withViewState -} from "../../StandardUserInterface/ViewStateContext"; +import { onStoryButtonClick } from "../../Map/MenuBar/StoryButton/StoryButton"; +import { WithViewState, withViewState } from "../../Context"; import { Story } from "../Story"; import Styles from "../story-panel.scss"; import StoryBody from "./StoryBody"; diff --git a/lib/ReactViews/Tools/DiffTool/DiffTool.tsx b/lib/ReactViews/Tools/DiffTool/DiffTool.tsx index 3b6befd5cd9..c23842afd61 100644 --- a/lib/ReactViews/Tools/DiffTool/DiffTool.tsx +++ b/lib/ReactViews/Tools/DiffTool/DiffTool.tsx @@ -44,7 +44,7 @@ import { GLYPHS, StyledIcon } from "../../../Styled/Icon"; import Loader from "../../Loader"; import DatePicker from "./DatePicker"; import LocationPicker from "./LocationPicker"; -import { CLOSE_TOOL_ID } from "../../Map/Navigation/registerMapNavigations"; +import { CLOSE_TOOL_ID } from "../../Map/MapNavigation/registerMapNavigations"; const dateFormat = require("dateformat"); @@ -834,7 +834,6 @@ const CloseDifferenceButton = styled(Button)` left: 50%; transform: translateX(-50%); top: 18px; - padding: 0 20px; `; diff --git a/lib/ReactViews/Tools/PedestrianMode/PedestrianMode.tsx b/lib/ReactViews/Tools/PedestrianMode/PedestrianMode.tsx index 457effff180..de2322bc5df 100644 --- a/lib/ReactViews/Tools/PedestrianMode/PedestrianMode.tsx +++ b/lib/ReactViews/Tools/PedestrianMode/PedestrianMode.tsx @@ -8,7 +8,7 @@ import PositionRightOfWorkbench from "../../Workbench/PositionRightOfWorkbench"; import DropPedestrianToGround from "./DropPedestrianToGround"; import MiniMap, { getViewFromScene, MiniMapView } from "./MiniMap"; import MovementControls from "./MovementControls"; -import MeasureTool from "../../Map/Navigation/Items/MeasureTool"; +import { MeasureTool } from "../../Map/MapNavigation/Items"; // The desired camera height measured from the surface in metres export const PEDESTRIAN_HEIGHT = 1.7; diff --git a/lib/ReactViews/Tools/Tool.tsx b/lib/ReactViews/Tools/Tool.tsx index e096229466d..45176ae799a 100644 --- a/lib/ReactViews/Tools/Tool.tsx +++ b/lib/ReactViews/Tools/Tool.tsx @@ -11,7 +11,7 @@ import Terria from "../../Models/Terria"; import ViewerMode from "../../Models/ViewerMode"; import ViewState from "../../ReactViewModels/ViewState"; import MapNavigationItemController from "../../ViewModels/MapNavigation/MapNavigationItemController"; -import { useViewState } from "../StandardUserInterface/ViewStateContext"; +import { useViewState } from "../Context"; interface ToolProps { toolName: string; diff --git a/lib/ReactViews/Tour/TourPortal.jsx b/lib/ReactViews/Tour/TourPortal.jsx index b853f90fbb5..622fc879823 100644 --- a/lib/ReactViews/Tour/TourPortal.jsx +++ b/lib/ReactViews/Tour/TourPortal.jsx @@ -23,7 +23,7 @@ import { parseCustomMarkdownToReactWithOptions } from "../Custom/parseCustomMark import Caret from "../Generic/Caret"; import CloseButton from "../Generic/CloseButton"; import { useWindowSize } from "../Hooks/useWindowSize"; -import { useViewState } from "../StandardUserInterface/ViewStateContext"; +import { useViewState } from "../Context"; import { applyTranslationIfExists } from "./../../Language/languageHelpers"; import { calculateLeftPosition, diff --git a/lib/ReactViews/WelcomeMessage/WelcomeMessage.jsx b/lib/ReactViews/WelcomeMessage/WelcomeMessage.jsx index 0a594033717..1e1381c0780 100644 --- a/lib/ReactViews/WelcomeMessage/WelcomeMessage.jsx +++ b/lib/ReactViews/WelcomeMessage/WelcomeMessage.jsx @@ -12,7 +12,7 @@ import Text, { TextSpan } from "../../Styled/Text"; import { ExplorerWindowElementName } from "../ExplorerWindow/ExplorerWindow"; import { useKeyPress } from "../Hooks/useKeyPress.js"; import VideoGuide from "../Map/Panels/HelpPanel/VideoGuide"; -import { withViewState } from "../StandardUserInterface/ViewStateContext"; +import { withViewState } from "../Context"; import { TourPortalDisplayName } from "../Tour/TourPortal"; import FadeIn from "../Transitions/FadeIn/FadeIn"; import SlideUpFadeIn from "../Transitions/SlideUpFadeIn/SlideUpFadeIn"; diff --git a/lib/ReactViews/Map/Panels/TerrainSide.tsx b/lib/ReactViews/Workbench/TerrainSide.tsx similarity index 92% rename from lib/ReactViews/Map/Panels/TerrainSide.tsx rename to lib/ReactViews/Workbench/TerrainSide.tsx index 7390ad0fb77..6d9c94fd7b2 100644 --- a/lib/ReactViews/Map/Panels/TerrainSide.tsx +++ b/lib/ReactViews/Workbench/TerrainSide.tsx @@ -4,13 +4,13 @@ import React from "react"; import { useTranslation } from "react-i18next"; import { useTheme } from "styled-components"; import SplitDirection from "terriajs-cesium/Source/Scene/SplitDirection"; -import Terria from "../../../Models/Terria"; -import ViewerMode from "../../../Models/ViewerMode"; -import Box from "../../../Styled/Box"; -import Checkbox from "../../../Styled/Checkbox/Checkbox"; -import { TextSpan } from "../../../Styled/Text"; -import { RawButton } from "./../../../Styled/Button"; -import { Spacing } from "./../../../Styled/Spacing"; +import Terria from "../../Models/Terria"; +import ViewerMode from "../../Models/ViewerMode"; +import Box from "../../Styled/Box"; +import Checkbox from "../../Styled/Checkbox/Checkbox"; +import { TextSpan } from "../../Styled/Text"; +import { RawButton } from "../../Styled/Button"; +import { Spacing } from "../../Styled/Spacing"; const sides = { left: "settingPanel.terrain.left", diff --git a/lib/ReactViews/Workbench/WorkbenchSplitScreen.tsx b/lib/ReactViews/Workbench/WorkbenchSplitScreen.tsx index 924354e1d26..578aa8528f2 100644 --- a/lib/ReactViews/Workbench/WorkbenchSplitScreen.tsx +++ b/lib/ReactViews/Workbench/WorkbenchSplitScreen.tsx @@ -11,7 +11,7 @@ import Box from "../../Styled/Box"; import { RawButton } from "../../Styled/Button"; import { GLYPHS, StyledIcon } from "../../Styled/Icon"; import Spacing from "../../Styled/Spacing"; -import TerrainSide from "../Map/Panels/TerrainSide"; +import TerrainSide from "./TerrainSide"; interface IWorkbenchSplitScreenProps { terria: Terria; diff --git a/lib/ReactViews/Workflow/SelectableDimensionWorkflow.tsx b/lib/ReactViews/Workflow/SelectableDimensionWorkflow.tsx index 84401e5eb66..3989e048f74 100644 --- a/lib/ReactViews/Workflow/SelectableDimensionWorkflow.tsx +++ b/lib/ReactViews/Workflow/SelectableDimensionWorkflow.tsx @@ -5,7 +5,7 @@ import { useTranslation } from "react-i18next"; import { getName } from "../../ModelMixins/CatalogMemberMixin"; import { filterSelectableDimensions } from "../../Models/SelectableDimensions/SelectableDimensions"; import SelectableDimension from "../SelectableDimensions/SelectableDimension"; -import { useViewState } from "../StandardUserInterface/ViewStateContext"; +import { useViewState } from "../Context"; import WorkbenchItemControls, { hideAllControls } from "../Workbench/Controls/WorkbenchItemControls"; diff --git a/lib/Styled/Text.tsx b/lib/Styled/Text.tsx index 4c9cae1c2db..972c869eabe 100644 --- a/lib/Styled/Text.tsx +++ b/lib/Styled/Text.tsx @@ -32,7 +32,7 @@ interface ITextWeight { interface ITextPropsBase { displayBlock?: boolean; isLink?: boolean; - nunito?: boolean; + mono?: boolean; openSans?: boolean; breakWord?: boolean; uppercase?: boolean; @@ -67,6 +67,8 @@ export const Text = styled.div` // TODO: themeify family font-family: ${props => props.theme.fontBase}; + + ${props => props.mono && `font-family: ${props.theme.fontMono};`} ${props => props.breakWord && @@ -184,11 +186,6 @@ export const Text = styled.div` ` font-size: ${props.styledFontSize}; `} - ${props => - props.styledLineHeight && - ` - line-height: ${props.styledLineHeight}; - `} ${props => props.highlightLinks && diff --git a/lib/ThirdParty/terriajs-cesium-extra/index.d.ts b/lib/ThirdParty/terriajs-cesium-extra/index.d.ts index a173ff3c2e6..b39d29200e6 100644 --- a/lib/ThirdParty/terriajs-cesium-extra/index.d.ts +++ b/lib/ThirdParty/terriajs-cesium-extra/index.d.ts @@ -53,4 +53,5 @@ declare interface FeatureDetection { isEdge(): boolean; isInternetExplorer(): boolean; internetExplorerVersion(): number[]; + chromeVersion(): number[]; } diff --git a/test/Map/StyledHtmlSpec.tsx b/test/Map/StyledHtmlSpec.tsx index 1cd3cee964c..ddf46cb2d89 100644 --- a/test/Map/StyledHtmlSpec.tsx +++ b/test/Map/StyledHtmlSpec.tsx @@ -5,7 +5,7 @@ import { ThemeProvider } from "styled-components"; import { act } from "react-dom/test-utils"; import Terria from "../../lib/Models/Terria"; import ViewState from "../../lib/ReactViewModels/ViewState"; -import { terriaTheme } from "../../lib/ReactViews/StandardUserInterface/StandardTheme"; +import { terriaTheme } from "../../lib/ReactViews/StandardUserInterface"; import { StyledHtmlRaw } from "../../lib/ReactViews/Map/Panels/HelpPanel/StyledHtml"; import { TooltipWithButtonLauncher } from "../../lib/ReactViews/Generic/TooltipWrapper"; import registerCustomComponentTypes from "../../lib/ReactViews/Custom/registerCustomComponentTypes"; diff --git a/test/ReactViews/ClipboardSpec.tsx b/test/ReactViews/ClipboardSpec.tsx index 407fceee603..9bb3674a875 100644 --- a/test/ReactViews/ClipboardSpec.tsx +++ b/test/ReactViews/ClipboardSpec.tsx @@ -2,7 +2,7 @@ const create: any = require("react-test-renderer").create; import React from "react"; import { act } from "react-dom/test-utils"; import { ThemeProvider } from "styled-components"; -import { terriaTheme } from "../../lib/ReactViews/StandardUserInterface/StandardTheme"; +import { terriaTheme } from "../../lib/ReactViews/StandardUserInterface"; import Clipboard from "../../lib/ReactViews/Clipboard"; import Input from "../../lib/Styled/Input"; import Button from "../../lib/Styled/Button"; diff --git a/test/ReactViews/DimensionSelectorSectionSpec.tsx b/test/ReactViews/DimensionSelectorSectionSpec.tsx index 37f96fb58d7..7fd2fab99f9 100644 --- a/test/ReactViews/DimensionSelectorSectionSpec.tsx +++ b/test/ReactViews/DimensionSelectorSectionSpec.tsx @@ -15,7 +15,7 @@ import SelectableDimensions, { import Terria from "../../lib/Models/Terria"; import { SelectableDimensionGroup } from "../../lib/ReactViews/SelectableDimensions/Group"; import SelectableDimension from "../../lib/ReactViews/SelectableDimensions/SelectableDimension"; -import { terriaTheme } from "../../lib/ReactViews/StandardUserInterface/StandardTheme"; +import { terriaTheme } from "../../lib/ReactViews/StandardUserInterface"; import SelectableDimensionSection from "../../lib/ReactViews/Workbench/Controls/SelectableDimensionSection"; import Checkbox from "../../lib/Styled/Checkbox"; import CatalogMemberTraits from "../../lib/Traits/TraitsClasses/CatalogMemberTraits"; diff --git a/test/ReactViews/Generic/PromptSpec.tsx b/test/ReactViews/Generic/PromptSpec.tsx index 0f37b725af3..59c41d9c017 100644 --- a/test/ReactViews/Generic/PromptSpec.tsx +++ b/test/ReactViews/Generic/PromptSpec.tsx @@ -5,7 +5,7 @@ import Terria from "../../../lib/Models/Terria"; import ViewState from "../../../lib/ReactViewModels/ViewState"; import { runInAction } from "mobx"; const Prompt: any = require("../../../lib/ReactViews/Generic/Prompt").default; -import { terriaTheme } from "../../../lib/ReactViews/StandardUserInterface/StandardTheme"; +import { terriaTheme } from "../../../lib/ReactViews/StandardUserInterface"; import Caret from "../../../lib/ReactViews/Generic/Caret"; describe("HelpPrompt", function() { diff --git a/test/ReactViews/Map/Navigation/Compass/CompassSpec.tsx b/test/ReactViews/Map/Navigation/Compass/CompassSpec.tsx index 6d985e9cf77..befff7771e9 100644 --- a/test/ReactViews/Map/Navigation/Compass/CompassSpec.tsx +++ b/test/ReactViews/Map/Navigation/Compass/CompassSpec.tsx @@ -5,10 +5,8 @@ import { act } from "react-dom/test-utils"; import Terria from "../../../../../lib/Models/Terria"; import ViewState from "../../../../../lib/ReactViewModels/ViewState"; import { ThemeProvider } from "styled-components"; -import { terriaTheme } from "../../../../../lib/ReactViews/StandardUserInterface/StandardTheme"; -// import Compass from "../../../../../lib/ReactViews/Map/Navigation/Compass"; -const Compass: any = require("../../../../../lib/ReactViews/Map/Navigation/Items/Compass") - .default; +import { terriaTheme } from "../../../../../lib/ReactViews/StandardUserInterface"; +import { Compass } from "../../../../../lib/ReactViews/Map/MapNavigation/Items/Compass/Compass"; import { StyledIcon } from "../../../../../lib/Styled/Icon"; describe("Compass", function() { diff --git a/test/ReactViews/GyroscopeGuidance/GyroscopeGuidanceSpec.tsx b/test/ReactViews/Map/Navigation/Compass/GyroscopeGuidanceSpec.tsx similarity index 74% rename from test/ReactViews/GyroscopeGuidance/GyroscopeGuidanceSpec.tsx rename to test/ReactViews/Map/Navigation/Compass/GyroscopeGuidanceSpec.tsx index 2547dc23091..f1b600f049b 100644 --- a/test/ReactViews/GyroscopeGuidance/GyroscopeGuidanceSpec.tsx +++ b/test/ReactViews/Map/Navigation/Compass/GyroscopeGuidanceSpec.tsx @@ -1,10 +1,10 @@ const create: any = require("react-test-renderer").create; import React from "react"; import { act } from "react-dom/test-utils"; -import Terria from "../../../lib/Models/Terria"; -import ViewState from "../../../lib/ReactViewModels/ViewState"; -import GyroscopeGuidance from "../../../lib/ReactViews/GyroscopeGuidance/GyroscopeGuidance"; -import MapIconButton from "../../../lib/ReactViews/MapIconButton/MapIconButton"; +import Terria from "../../../../../lib/Models/Terria"; +import ViewState from "../../../../../lib/ReactViewModels/ViewState"; +import { GyroscopeGuidance } from "../../../../../lib/ReactViews/Map/MapNavigation/Items/Compass/GyroscopeGuidance"; +import MapIconButton from "../../../../../lib/ReactViews/MapIconButton/MapIconButton"; describe("GyroscopeGuidance", function() { let terria: Terria; diff --git a/test/ReactViews/Map/Panels/HelpPanel/VideoGuideSpec.tsx b/test/ReactViews/Map/Panels/HelpPanel/VideoGuideSpec.tsx index f986b0e52bd..e0a3ccaf01b 100644 --- a/test/ReactViews/Map/Panels/HelpPanel/VideoGuideSpec.tsx +++ b/test/ReactViews/Map/Panels/HelpPanel/VideoGuideSpec.tsx @@ -2,7 +2,7 @@ const create: any = require("react-test-renderer").create; import React from "react"; import { act } from "react-dom/test-utils"; import { ThemeProvider } from "styled-components"; -import { terriaTheme } from "../../../../../lib/ReactViews/StandardUserInterface/StandardTheme"; +import { terriaTheme } from "../../../../../lib/ReactViews/StandardUserInterface"; import Terria from "../../../../../lib/Models/Terria"; import ViewState from "../../../../../lib/ReactViewModels/ViewState"; const VideoGuide: any = require("../../../../../lib/ReactViews/Map/Panels/HelpPanel/VideoGuide") diff --git a/test/ReactViews/MeasureToolSpec.jsx b/test/ReactViews/MeasureToolSpec.jsx index 0b644e087f8..1fbe8b48413 100644 --- a/test/ReactViews/MeasureToolSpec.jsx +++ b/test/ReactViews/MeasureToolSpec.jsx @@ -5,7 +5,7 @@ import React from "react"; import Terria from "../../lib/Models/Terria"; import { getMountedInstance } from "./MoreShallowTools"; -import { MeasureTool } from "../../lib/ReactViews/Map/Navigation/MeasureTool"; +import { MeasureTool } from "../../lib/ReactViews/Map/MapNavigation/MeasureTool"; const Entity = require("terriajs-cesium/Source/DataSources/Entity.js").default; const Ellipsoid = require("terriajs-cesium/Source/Core/Ellipsoid.js").default; const ConstantPositionProperty = require("terriajs-cesium/Source/DataSources/ConstantPositionProperty.js") diff --git a/test/ReactViews/Preview/DescriptionSpec.tsx b/test/ReactViews/Preview/DescriptionSpec.tsx index 93e2951f666..77ae47c5e7b 100644 --- a/test/ReactViews/Preview/DescriptionSpec.tsx +++ b/test/ReactViews/Preview/DescriptionSpec.tsx @@ -7,7 +7,7 @@ import Terria from "../../../lib/Models/Terria"; import updateModelFromJson from "../../../lib/Models/Definition/updateModelFromJson"; import WebMapServiceCatalogItem from "../../../lib/Models/Catalog/Ows/WebMapServiceCatalogItem"; import Description from "../../../lib/ReactViews/Preview/Description"; -import { terriaTheme } from "../../../lib/ReactViews/StandardUserInterface/StandardTheme"; +import { terriaTheme } from "../../../lib/ReactViews/StandardUserInterface"; describe("DescriptionSpec", function() { let testRenderer: ReactTestRenderer; diff --git a/test/ReactViews/Search/BreadcrumbsSpec.tsx b/test/ReactViews/Search/BreadcrumbsSpec.tsx index 346db0ce86e..28c70fb927d 100644 --- a/test/ReactViews/Search/BreadcrumbsSpec.tsx +++ b/test/ReactViews/Search/BreadcrumbsSpec.tsx @@ -9,7 +9,7 @@ const DataCatalogTab: any = require("../../../lib/ReactViews/ExplorerWindow/Tabs .default; import Icon from "../../../lib/Styled/Icon"; import { ThemeProvider } from "styled-components"; -import { terriaTheme } from "../../../lib/ReactViews/StandardUserInterface/StandardTheme"; +import { terriaTheme } from "../../../lib/ReactViews/StandardUserInterface"; import { runInAction } from "mobx"; describe("Breadcrumbs", function() { diff --git a/test/ReactViews/Search/SearchBoxAndResultsSpec.tsx b/test/ReactViews/Search/SearchBoxAndResultsSpec.tsx index 4639acc0e23..3378b541bdb 100644 --- a/test/ReactViews/Search/SearchBoxAndResultsSpec.tsx +++ b/test/ReactViews/Search/SearchBoxAndResultsSpec.tsx @@ -8,7 +8,7 @@ import SearchBoxAndResults, { SearchInDataCatalog } from "../../../lib/ReactViews/Search/SearchBoxAndResults"; import { ThemeProvider } from "styled-components"; -import { terriaTheme } from "../../../lib/ReactViews/StandardUserInterface/StandardTheme"; +import { terriaTheme } from "../../../lib/ReactViews/StandardUserInterface"; describe("SearchBoxAndResults", function() { let terria: Terria; diff --git a/test/ReactViews/Search/SearchBoxSpec.tsx b/test/ReactViews/Search/SearchBoxSpec.tsx index cfa30286881..7125cfdaada 100644 --- a/test/ReactViews/Search/SearchBoxSpec.tsx +++ b/test/ReactViews/Search/SearchBoxSpec.tsx @@ -4,7 +4,7 @@ import { act } from "react-dom/test-utils"; import Terria from "../../../lib/Models/Terria"; import ViewState from "../../../lib/ReactViewModels/ViewState"; import { SearchBox } from "../../../lib/ReactViews/Search/SearchBox"; -import { terriaTheme } from "../../../lib/ReactViews/StandardUserInterface/StandardTheme"; +import { terriaTheme } from "../../../lib/ReactViews/StandardUserInterface"; describe("SearchBox", function() { let terria: Terria; diff --git a/test/ReactViews/ShortReportSpec.tsx b/test/ReactViews/ShortReportSpec.tsx index 8c9255eb427..248c4339c0e 100644 --- a/test/ReactViews/ShortReportSpec.tsx +++ b/test/ReactViews/ShortReportSpec.tsx @@ -8,7 +8,7 @@ import { import { ThemeProvider } from "styled-components"; import WebMapServiceCatalogItem from "../../lib/Models/Catalog/Ows/WebMapServiceCatalogItem"; import Terria from "../../lib/Models/Terria"; -import { terriaTheme } from "../../lib/ReactViews/StandardUserInterface/StandardTheme"; +import { terriaTheme } from "../../lib/ReactViews/StandardUserInterface"; import ShortReport from "../../lib/ReactViews/Workbench/Controls/ShortReport"; import Text from "../../lib/Styled/Text"; diff --git a/test/ReactViews/Map/TrainerBar/TrainerBarSpec.tsx b/test/ReactViews/StandardUserInterface/TrainerBar/TrainerBarSpec.tsx similarity index 96% rename from test/ReactViews/Map/TrainerBar/TrainerBarSpec.tsx rename to test/ReactViews/StandardUserInterface/TrainerBar/TrainerBarSpec.tsx index 4d38ca83333..a701a22bc62 100644 --- a/test/ReactViews/Map/TrainerBar/TrainerBarSpec.tsx +++ b/test/ReactViews/StandardUserInterface/TrainerBar/TrainerBarSpec.tsx @@ -3,7 +3,7 @@ import React from "react"; import { act } from "react-dom/test-utils"; import Terria from "../../../../lib/Models/Terria"; import ViewState from "../../../../lib/ReactViewModels/ViewState"; -import TrainerBar from "../../../../lib/ReactViews/Map/TrainerBar/TrainerBar"; +import TrainerBar from "../../../../lib/ReactViews/StandardUserInterface/TrainerBar/TrainerBar"; import Box from "../../../../lib/Styled/Box"; import { createWithContexts } from "../../withContext"; import TestHelpContent from "./test-help-content"; diff --git a/test/ReactViews/Map/TrainerBar/test-help-content.js b/test/ReactViews/StandardUserInterface/TrainerBar/test-help-content.js similarity index 100% rename from test/ReactViews/Map/TrainerBar/test-help-content.js rename to test/ReactViews/StandardUserInterface/TrainerBar/test-help-content.js diff --git a/test/ReactViews/WarningBoxSpec.tsx b/test/ReactViews/WarningBoxSpec.tsx index 417fc486c8c..9fe254d2f8d 100644 --- a/test/ReactViews/WarningBoxSpec.tsx +++ b/test/ReactViews/WarningBoxSpec.tsx @@ -2,7 +2,7 @@ import { create, ReactTestInstance } from "react-test-renderer"; import React from "react"; import { act } from "react-dom/test-utils"; import { ThemeProvider } from "styled-components"; -import { terriaTheme } from "../../lib/ReactViews/StandardUserInterface/StandardTheme"; +import { terriaTheme } from "../../lib/ReactViews/StandardUserInterface"; import WarningBox from "../../lib/ReactViews/Preview/WarningBox"; import Terria from "../../lib/Models/Terria"; import WebMapServiceCatalogItem from "../../lib/Models/Catalog/Ows/WebMapServiceCatalogItem"; diff --git a/test/ReactViews/withContext.tsx b/test/ReactViews/withContext.tsx index fcdcd03c866..35da0173e4d 100644 --- a/test/ReactViews/withContext.tsx +++ b/test/ReactViews/withContext.tsx @@ -2,8 +2,8 @@ import React from "react"; import { create, TestRendererOptions } from "react-test-renderer"; import { ThemeProvider } from "styled-components"; import ViewState from "../../lib/ReactViewModels/ViewState"; -import { terriaTheme } from "../../lib/ReactViews/StandardUserInterface/StandardTheme"; -import { ViewStateProvider } from "../../lib/ReactViews/StandardUserInterface/ViewStateContext"; +import { terriaTheme } from "../../lib/ReactViews/StandardUserInterface"; +import { ViewStateProvider } from "../../lib/ReactViews/Context/ViewStateContext"; export function withThemeContext(node: React.ReactNode) { return {node}; From 88cf8f6e309ff561f8a940e1b4b22f45adbe99f9 Mon Sep 17 00:00:00 2001 From: Zoran Kokeza Date: Thu, 4 May 2023 13:14:42 +0200 Subject: [PATCH 03/15] organize imports --- lib/ReactViews/Map/BottomBar/BottomBar.tsx | 4 ++-- lib/ReactViews/Map/BottomBar/LocationBar.tsx | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/ReactViews/Map/BottomBar/BottomBar.tsx b/lib/ReactViews/Map/BottomBar/BottomBar.tsx index 5e04dc4b151..1ce3331cefe 100644 --- a/lib/ReactViews/Map/BottomBar/BottomBar.tsx +++ b/lib/ReactViews/Map/BottomBar/BottomBar.tsx @@ -1,7 +1,7 @@ -import React, { VFC } from "react"; +import { VFC } from "react"; import Box from "../../../Styled/Box"; -import { MapCredits } from "./Credits"; import { useViewState } from "../../Context"; +import { MapCredits } from "./Credits"; import { DistanceLegend } from "./DistanceLegend"; import { LocationBar } from "./LocationBar"; diff --git a/lib/ReactViews/Map/BottomBar/LocationBar.tsx b/lib/ReactViews/Map/BottomBar/LocationBar.tsx index 4d5e0d869b9..0eb8b42a2c7 100644 --- a/lib/ReactViews/Map/BottomBar/LocationBar.tsx +++ b/lib/ReactViews/Map/BottomBar/LocationBar.tsx @@ -1,11 +1,10 @@ import { observer } from "mobx-react"; -import React, { FC, RefObject, useEffect, useRef } from "react"; +import { FC, RefObject, useEffect, useRef } from "react"; import { useTranslation } from "react-i18next"; import styled, { useTheme } from "styled-components"; import MouseCoords from "../../../ReactViewModels/MouseCoords"; import Box from "../../../Styled/Box"; import { RawButton } from "../../../Styled/Button"; -import { TextSpan } from "../../../Styled/Text"; interface ILocationBarProps { mouseCoords: MouseCoords; From ec738b2fef25109daf767ade97fb10f0172db861 Mon Sep 17 00:00:00 2001 From: Staf Smith Date: Fri, 14 Jul 2023 10:53:54 +0800 Subject: [PATCH 04/15] Add react imports to ix errors --- lib/ReactViews/Map/BottomBar/BottomBar.tsx | 1 + lib/ReactViews/Map/BottomBar/LocationBar.tsx | 1 + 2 files changed, 2 insertions(+) diff --git a/lib/ReactViews/Map/BottomBar/BottomBar.tsx b/lib/ReactViews/Map/BottomBar/BottomBar.tsx index 1ce3331cefe..cd903ba6e3c 100644 --- a/lib/ReactViews/Map/BottomBar/BottomBar.tsx +++ b/lib/ReactViews/Map/BottomBar/BottomBar.tsx @@ -4,6 +4,7 @@ import { useViewState } from "../../Context"; import { MapCredits } from "./Credits"; import { DistanceLegend } from "./DistanceLegend"; import { LocationBar } from "./LocationBar"; +import React from "react"; export const BottomBar: VFC = () => { const viewState = useViewState(); diff --git a/lib/ReactViews/Map/BottomBar/LocationBar.tsx b/lib/ReactViews/Map/BottomBar/LocationBar.tsx index 0eb8b42a2c7..a8b99e2133c 100644 --- a/lib/ReactViews/Map/BottomBar/LocationBar.tsx +++ b/lib/ReactViews/Map/BottomBar/LocationBar.tsx @@ -1,3 +1,4 @@ +import React from "react"; import { observer } from "mobx-react"; import { FC, RefObject, useEffect, useRef } from "react"; import { useTranslation } from "react-i18next"; From 7d9f5b4309854f25151dfff75d4efe1efb05bee8 Mon Sep 17 00:00:00 2001 From: Staf Smith Date: Mon, 17 Jul 2023 15:43:15 +0800 Subject: [PATCH 05/15] Fix import in test --- test/ReactViews/Map/Navigation/Compass/CompassSpec.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/ReactViews/Map/Navigation/Compass/CompassSpec.tsx b/test/ReactViews/Map/Navigation/Compass/CompassSpec.tsx index ec3d1e2afc7..d88e6da7f4f 100644 --- a/test/ReactViews/Map/Navigation/Compass/CompassSpec.tsx +++ b/test/ReactViews/Map/Navigation/Compass/CompassSpec.tsx @@ -6,7 +6,7 @@ import Terria from "../../../../../lib/Models/Terria"; import ViewState from "../../../../../lib/ReactViewModels/ViewState"; import { ThemeProvider } from "styled-components"; import { terriaTheme } from "../../../../../lib/ReactViews/StandardUserInterface"; -import { Compass } from "../../../../../lib/ReactViews/Map/MapNavigation/Items/Compass/Compass"; +import Compass from "../../../../../lib/ReactViews/Map/MapNavigation/Items/Compass/Compass"; import { StyledIcon } from "../../../../../lib/Styled/Icon"; describe("Compass", function () { From 053c27fcff5fbcb6e39a3c197b517fbcced76ef2 Mon Sep 17 00:00:00 2001 From: Staf Smith Date: Mon, 17 Jul 2023 16:01:16 +0800 Subject: [PATCH 06/15] Rem Splitter.jsx after checking Splitter.tsx --- lib/ReactViews/Map/Splitter.jsx | 231 -------------------------------- 1 file changed, 231 deletions(-) delete mode 100644 lib/ReactViews/Map/Splitter.jsx diff --git a/lib/ReactViews/Map/Splitter.jsx b/lib/ReactViews/Map/Splitter.jsx deleted file mode 100644 index 9031e37bd44..00000000000 --- a/lib/ReactViews/Map/Splitter.jsx +++ /dev/null @@ -1,231 +0,0 @@ -import React from "react"; -import PropTypes from "prop-types"; -import { withTranslation } from "react-i18next"; -import { GLYPHS, StyledIcon } from "../../Styled/Icon"; -import Styles from "./splitter.scss"; -import { observer } from "mobx-react"; -import { runInAction } from "mobx"; - -// Feature detect support for passive: true in event subscriptions. -// See https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Safely_detecting_option_support -let passiveSupported = false; -try { - const options = Object.defineProperty({}, "passive", { - get: function () { - passiveSupported = true; - return true; - } - }); - - window.addEventListener("test", null, options); - window.removeEventListener("test", null, options); -} catch (err) {} - -const notPassive = passiveSupported ? { passive: false } : false; - -@observer -class Splitter extends React.Component { - static propTypes = { - terria: PropTypes.object.isRequired, - viewState: PropTypes.object.isRequired, - thumbSize: PropTypes.number, - padding: PropTypes.number, - t: PropTypes.func.isRequired - }; - - static defaultProps = { - thumbSize: 42, - padding: 0 - }; - - constructor(props) { - super(props); - this.forceRefresh = this.forceRefresh.bind(this); - this.drag = this.drag.bind(this); - this.startDrag = this.startDrag.bind(this); - this.stopDrag = this.stopDrag.bind(this); - } - - componentDidMount() { - const that = this; - window.addEventListener("resize", function () { - that.forceRefresh(); - }); - } - - componentWillUnmount() { - this.unsubscribe(); - } - - forceRefresh() { - const smallChange = - this.props.terria.splitPosition < 0.5 ? 0.0001 : -0.0001; // Make sure never <0 or >1. - runInAction(() => { - this.props.terria.splitPosition += smallChange; - }); - } - - startDrag(event) { - const viewer = this.props.terria.currentViewer; - viewer.pauseMapInteraction(); - - // While dragging is in progress, subscribe to document-level movement and up events. - document.addEventListener("mousemove", this.drag, notPassive); - document.addEventListener("touchmove", this.drag, notPassive); - document.addEventListener("mouseup", this.stopDrag, notPassive); - document.addEventListener("touchend", this.stopDrag, notPassive); - - event.preventDefault(); - event.stopPropagation(); - } - - drag(event) { - let clientX = event.clientX; - let clientY = event.clientY; - if (event.targetTouches && event.targetTouches.length > 0) { - clientX = event.targetTouches.item(0).clientX; - clientY = event.targetTouches.item(0).clientY; - } - - const viewer = this.props.terria.mainViewer.currentViewer; - const container = viewer.getContainer(); - const mapRect = container.getBoundingClientRect(); - - const that = this; - function computeSplitFraction(startBound, endBound, position) { - const difference = endBound - startBound; - const fraction = (position - startBound) / difference; - - const min = startBound + that.props.padding + that.props.thumbSize * 0.5; - const max = endBound - that.props.padding - that.props.thumbSize * 0.5; - const minFraction = (min - startBound) / difference; - const maxFraction = (max - startBound) / difference; - - return Math.min(maxFraction, Math.max(minFraction, fraction)); - } - let splitFractionX = computeSplitFraction( - mapRect.left, - mapRect.right, - clientX - ); - let splitFractionY = computeSplitFraction( - mapRect.top, - mapRect.bottom, - clientY - ); - - // We compute the maximum and minium windows bounds as a percentage so that we can always apply the bounds - // restriction as a percentage for consistency (we currently use absolute values for X and percentage values for - // Y, but always apply the constraint as a percentage). - // We use absolute pixel values for horizontal restriction because of the fixed UI elements which occupy an - // absolute amount of screen relestate and 100 px seems like a fine amount for the current UI. - const minX = computeSplitFraction( - mapRect.left, - mapRect.right, - mapRect.left + 100 - ); - const maxX = computeSplitFraction( - mapRect.left, - mapRect.right, - mapRect.right - 100 - ); - // Resctrict to within +/-30% of the center vertically (so we don't run into the top and bottom UI elements). - const minY = 0.2; - const maxY = 0.8; - - splitFractionX = Math.min(maxX, Math.max(minX, splitFractionX)); - splitFractionY = Math.min(maxY, Math.max(minY, splitFractionY)); - - runInAction(() => { - this.props.terria.splitPosition = splitFractionX; - this.props.terria.splitPositionVertical = splitFractionY; - }); - - event.preventDefault(); - event.stopPropagation(); - } - - stopDrag(event) { - this.unsubscribe(); - - const viewer = this.props.terria.currentViewer; - // Ensure splitter stays in sync with map - this.props.viewState.triggerResizeEvent(); - - viewer.resumeMapInteraction(); - - event.preventDefault(); - event.stopPropagation(); - } - - unsubscribe() { - document.removeEventListener("mousemove", this.drag, notPassive); - document.removeEventListener("touchmove", this.drag, notPassive); - document.removeEventListener("mouseup", this.stopDrag, notPassive); - document.removeEventListener("touchend", this.stopDrag, notPassive); - window.removeEventListener("resize", this.forceRefresh); - } - - getPosition() { - const canvasWidth = - this.props.terria.currentViewer.getContainer().clientWidth; - const canvasHeight = - this.props.terria.currentViewer.getContainer().clientHeight; - return { - x: this.props.terria.splitPosition * canvasWidth, - y: this.props.terria.splitPositionVertical * canvasHeight - }; - } - - render() { - if ( - !this.props.terria.showSplitter || - !this.props.terria.currentViewer.canShowSplitter || - !this.props.terria.currentViewer.getContainer() - ) { - return null; - } - - const thumbWidth = this.props.thumbSize; - const position = this.getPosition(); - - const dividerStyle = { - left: position.x + "px", - backgroundColor: this.props.terria.baseMapContrastColor - }; - - const thumbStyle = { - left: position.x + "px", - top: position.y + "px", - width: thumbWidth + "px", - height: thumbWidth + "px", - marginLeft: "-" + thumbWidth * 0.5 + "px", - marginTop: "-" + thumbWidth * 0.5 + "px", - lineHeight: thumbWidth - 2 + "px", - borderRadius: thumbWidth * 0.5 + "px", - fontSize: thumbWidth - 12 + "px" - }; - - const { t } = this.props; - - return ( -
-
-
-
- -
- ); - } -} - -module.exports = withTranslation()(Splitter); From dd4f9901c7b1da473d6f5eafc94dc38d27a64570 Mon Sep 17 00:00:00 2001 From: Staf Smith Date: Tue, 18 Jul 2023 13:22:32 +0800 Subject: [PATCH 07/15] Small changes to ProgressBar.tsx --- lib/ReactViews/Map/ProgressBar.tsx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/ReactViews/Map/ProgressBar.tsx b/lib/ReactViews/Map/ProgressBar.tsx index 694079a4748..9fcc5359d60 100644 --- a/lib/ReactViews/Map/ProgressBar.tsx +++ b/lib/ReactViews/Map/ProgressBar.tsx @@ -1,5 +1,5 @@ import React, { VFC, useCallback, useEffect, useMemo, useState } from "react"; -import styled, { keyframes, useTheme } from "styled-components"; +import styled, { css, keyframes, useTheme } from "styled-components"; import EventHelper from "terriajs-cesium/Source/Core/EventHelper"; import { useViewState } from "../Context"; @@ -16,7 +16,7 @@ export const ProgressBar: VFC = () => { setLoadPercentage(sanitisedPercentage); }, []); - const setMode = (mode: any) => { + const setMode = (mode: boolean) => { setIndeterminateLoading(mode); }; @@ -37,7 +37,7 @@ export const ProgressBar: VFC = () => { terria.baseMapContrastColor === "#ffffff" ? "#ffffff" : theme.colorPrimary, - [] + [terria.baseMapContrastColor] ); const allComplete = loadPercentage === 100 && !indeterminateLoading; @@ -70,11 +70,11 @@ const StyledProgressBar = styled.div` ${(props) => props.indeterminate && - ` - width: 100%; - animation: ${indeterminateAnimation} 1.2s infinite linear; - transform-origin: 0% 50%; - `} + css` + width: 100%; + animation: ${indeterminateAnimation} 1.2s infinite linear; + transform-origin: 0% 50%; + `} `; const indeterminateAnimation = keyframes` From f62bfafb3919ed8ac0499b32c9e0e30e9f3b16dc Mon Sep 17 00:00:00 2001 From: Staf Smith Date: Tue, 18 Jul 2023 13:23:21 +0800 Subject: [PATCH 08/15] Delete ProgressBar.jsx after checking TS version --- lib/ReactViews/Map/ProgressBar.jsx | 99 ------------------------------ 1 file changed, 99 deletions(-) delete mode 100644 lib/ReactViews/Map/ProgressBar.jsx diff --git a/lib/ReactViews/Map/ProgressBar.jsx b/lib/ReactViews/Map/ProgressBar.jsx deleted file mode 100644 index 65cb08c0eaf..00000000000 --- a/lib/ReactViews/Map/ProgressBar.jsx +++ /dev/null @@ -1,99 +0,0 @@ -import classNames from "classnames"; -import { observer } from "mobx-react"; -import PropTypes from "prop-types"; -import React from "react"; -import { withTheme } from "styled-components"; -import EventHelper from "terriajs-cesium/Source/Core/EventHelper"; -import { withViewState } from "../StandardUserInterface/ViewStateContext"; -import Styles from "./progress-bar.scss"; - -// The map navigation region -@observer -class ProgressBar extends React.Component { - static propTypes = { - viewState: PropTypes.object.isRequired, - theme: PropTypes.object.isRequired - }; - - constructor(props) { - super(props); - this.state = { - visible: "hidden" - }; - } - - /* eslint-disable-next-line camelcase */ - UNSAFE_componentWillMount() { - this.eventHelper = new EventHelper(); - - this.eventHelper.add( - this.props.viewState.terria.tileLoadProgressEvent, - this.setProgress.bind(this) - ); - - // Also listen for indeterminate data source loading events - this.eventHelper.add( - this.props.viewState.terria.indeterminateTileLoadProgressEvent, - this.setMode.bind(this) - ); - - // TODO - is this actually needed now? load events always get called when - // changing viewer. if still reuqired, - // clear progress when new viewer observed, rather than mounting to a 'current viewer' - - // // Clear progress when the viewer changes so we're not left with an invalid progress bar hanging on the screen. - // this.eventHelper.add( - // this.props.viewState.terria.currentViewer.beforeViewerChanged, - // this.setProgress.bind(this, 0, 0) - // ); - } - - setProgress(remaining, max) { - const rawPercentage = (1 - remaining / max) * 100; - const sanitisedPercentage = Math.floor(remaining > 0 ? rawPercentage : 100); - - this.setState({ - percentage: sanitisedPercentage - }); - } - - setMode(loading) { - this.setState({ loading: loading }); - } - - componentWillUnmount() { - this.eventHelper.removeAll(); - } - - /** - * Progress bar is influced by two loading states: - * The base globe where the progress bar shows actual progress, - * Sources where load progress is indeterminate including 3DTilesets where the progress bar is animated. - */ - render() { - const determinateProgress = this.state.percentage + "%"; - const indeterminateStillLoading = this.state.loading; - const allComplete = this.state.percentage === 100 && !this.state.loading; - - // use the baseMapContrastColor to ensure progress bar is visible on light backgrounds. If contrast color is white, use it. If its black, use the primary color of the current theme. - const backgroundColor = - this.props.viewState.terria.baseMapContrastColor === "#ffffff" - ? "#ffffff" - : this.props.theme.colorPrimary; - - return ( -
- ); - } -} - -export default withViewState(withTheme(ProgressBar)); From 67237d991bfef5b0fb1598777e61a0ea8eacf6d7 Mon Sep 17 00:00:00 2001 From: Staf Smith Date: Tue, 18 Jul 2023 15:00:46 +0800 Subject: [PATCH 09/15] Delete MapColumn.jsx after checking TS version --- .../StandardUserInterface/MapColumn.jsx | 215 ------------------ 1 file changed, 215 deletions(-) delete mode 100644 lib/ReactViews/StandardUserInterface/MapColumn.jsx diff --git a/lib/ReactViews/StandardUserInterface/MapColumn.jsx b/lib/ReactViews/StandardUserInterface/MapColumn.jsx deleted file mode 100644 index 1a7411ba12e..00000000000 --- a/lib/ReactViews/StandardUserInterface/MapColumn.jsx +++ /dev/null @@ -1,215 +0,0 @@ -import classNames from "classnames"; -import { observer } from "mobx-react"; -import PropTypes from "prop-types"; -import React from "react"; -import { withTranslation } from "react-i18next"; -import FeatureDetection from "terriajs-cesium/Source/Core/FeatureDetection"; -import ActionBarPortal from "../ActionBar/ActionBarPortal"; -import BottomDock from "../BottomDock/BottomDock"; -import { MapCredits } from "../Credits"; -import Loader from "../Loader"; -import BottomLeftBar from "../Map/BottomLeftBar/BottomLeftBar"; -import DistanceLegend from "../Map/Legend/DistanceLegend"; -import LocationBar from "../Map/Legend/LocationBar"; -import MenuBar from "../Map/MenuBar"; -import MapNavigation from "../Map/Navigation/MapNavigation"; -import TerriaViewerWrapper from "../Map/TerriaViewerWrapper"; -import SlideUpFadeIn from "../Transitions/SlideUpFadeIn/SlideUpFadeIn"; -import Styles from "./map-column.scss"; -import Toast from "./Toast"; -import { withViewState } from "./ViewStateContext"; - -const chromeVersion = FeatureDetection.chromeVersion(); - -/** - * Right-hand column that contains the map, controls that sit over the map and sometimes the bottom dock containing - * the timeline and charts. - */ -@observer -class MapColumn extends React.Component { - static propTypes = { - viewState: PropTypes.object.isRequired, - customFeedbacks: PropTypes.array.isRequired, - allBaseMaps: PropTypes.array.isRequired, - animationDuration: PropTypes.number.isRequired, - customElements: PropTypes.object.isRequired, - t: PropTypes.func.isRequired - }; - - constructor(props) { - super(props); - this.state = {}; - } - - render() { - const { customElements } = this.props; - const { t } = this.props; - // TODO: remove? see: https://bugs.chromium.org/p/chromium/issues/detail?id=1001663 - const isAboveChrome75 = - chromeVersion && chromeVersion[0] && Number(chromeVersion[0]) > 75; - const mapCellClass = classNames(Styles.mapCell, { - [Styles.mapCellChrome]: isAboveChrome75 - }); - return ( -
-
-
- -
- - -
-
-
- -
- - - - - - - - - -
- - -
-
- {/* TODO: re-implement/support custom feedbacks */} - {/* -
- -
-
*/} - - - -
{feedbackItem}
-
-
-
- - - -
- -
-
- -
-
-
-
- ); - } -} - -export default withTranslation()(withViewState(MapColumn)); From 91335393a83e1d260c8bad9f153fb920802eabec Mon Sep 17 00:00:00 2001 From: Staf Smith Date: Wed, 2 Aug 2023 10:44:36 +0800 Subject: [PATCH 10/15] Redo hide bottom dock with mapUI --- lib/ReactViews/Map/MapColumn.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ReactViews/Map/MapColumn.tsx b/lib/ReactViews/Map/MapColumn.tsx index a947682cbee..a412cf1e58c 100644 --- a/lib/ReactViews/Map/MapColumn.tsx +++ b/lib/ReactViews/Map/MapColumn.tsx @@ -120,7 +120,7 @@ export const MapColumn: FC = observer( )}
- {true && ( + {!viewState.hideMapUi && ( Date: Wed, 2 Aug 2023 11:04:53 +0800 Subject: [PATCH 11/15] re-implement conditional opacity --- lib/ReactViews/Map/MapColumn.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/ReactViews/Map/MapColumn.tsx b/lib/ReactViews/Map/MapColumn.tsx index a412cf1e58c..eb33ebc28c8 100644 --- a/lib/ReactViews/Map/MapColumn.tsx +++ b/lib/ReactViews/Map/MapColumn.tsx @@ -54,7 +54,11 @@ export const MapColumn: FC = observer(
{!viewState.hideMapUi && ( - <> +
= observer( navItems={customElements.nav} elementConfig={viewState.terria.elements.get("map-navigation")} /> - +
)} Date: Fri, 1 Sep 2023 16:58:24 +1000 Subject: [PATCH 12/15] Fix WMS null rectangle --- CHANGES.md | 1 + .../Catalog/Ows/WebMapServiceCapabilities.ts | 8 +- .../Ows/WebMapServiceCapabilitiesStratum.ts | 16 +- .../Ows/WebMapServiceCatalogItemSpec.ts | 32 + wwwroot/test/WMS/wms_nested_groups.xml | 1548 ++++++----------- 5 files changed, 541 insertions(+), 1064 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index e2f0cbb23c6..21e56591533 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -4,6 +4,7 @@ - Fixes broken point dragging interaction for user drawing in 3d-mode. - Added EPSG:7855 to `Proj4Definitions`. +- Add null check to `WebMapServiceCatalogItem` `rectangle` calculation - and now we ascend tree of WMS `Layers` until we find a rectangle. - [The next improvement] #### 8.3.2 - 2023-08-11 diff --git a/lib/Models/Catalog/Ows/WebMapServiceCapabilities.ts b/lib/Models/Catalog/Ows/WebMapServiceCapabilities.ts index 411c1074c62..804308108b0 100644 --- a/lib/Models/Catalog/Ows/WebMapServiceCapabilities.ts +++ b/lib/Models/Catalog/Ows/WebMapServiceCapabilities.ts @@ -132,7 +132,7 @@ type Mutable = { -readonly [P in keyof T]: T[P] }; export function getRectangleFromLayer( layer: CapabilitiesLayer ): StratumFromTraits | undefined { - var egbb = layer.EX_GeographicBoundingBox; // required in WMS 1.3.0 + var egbb = layer?.EX_GeographicBoundingBox; // required in WMS 1.3.0 if (egbb) { return { west: egbb.westBoundLongitude, @@ -141,7 +141,7 @@ export function getRectangleFromLayer( north: egbb.northBoundLatitude }; } else { - var llbb = layer.LatLonBoundingBox; // required in WMS 1.0.0 through 1.1.1 + var llbb = layer?.LatLonBoundingBox; // required in WMS 1.0.0 through 1.1.1 if (llbb) { return { west: llbb.minx, @@ -151,6 +151,10 @@ export function getRectangleFromLayer( }; } } + + // Work way through ancestors until we get a rectangle. + if (layer?._parent) return getRectangleFromLayer(layer._parent); + return undefined; } diff --git a/lib/Models/Catalog/Ows/WebMapServiceCapabilitiesStratum.ts b/lib/Models/Catalog/Ows/WebMapServiceCapabilitiesStratum.ts index 2460647f578..8cb7bff5b01 100644 --- a/lib/Models/Catalog/Ows/WebMapServiceCapabilitiesStratum.ts +++ b/lib/Models/Catalog/Ows/WebMapServiceCapabilitiesStratum.ts @@ -638,17 +638,27 @@ export default class WebMapServiceCapabilitiesStratum extends LoadableStratum( (unionRectangle, layer) => { // Convert to cesium Rectangle (so we can use Rectangle.union) const latLonRect = getRectangleFromLayer(layer); - const ceisumRect = Rectangle.fromDegrees( + + if ( + !isDefined(latLonRect?.west) || + !isDefined(latLonRect?.south) || + !isDefined(latLonRect?.east) || + !isDefined(latLonRect?.north) + ) + return; + + const cesiumRectangle = Rectangle.fromDegrees( latLonRect?.west, latLonRect?.south, latLonRect?.east, latLonRect?.north ); + if (!unionRectangle) { - return ceisumRect; + return cesiumRectangle; } - return Rectangle.union(unionRectangle, ceisumRect); + return Rectangle.union(unionRectangle, cesiumRectangle); }, undefined ); diff --git a/test/Models/Catalog/Ows/WebMapServiceCatalogItemSpec.ts b/test/Models/Catalog/Ows/WebMapServiceCatalogItemSpec.ts index 10a81afc216..05541195379 100644 --- a/test/Models/Catalog/Ows/WebMapServiceCatalogItemSpec.ts +++ b/test/Models/Catalog/Ows/WebMapServiceCatalogItemSpec.ts @@ -375,6 +375,38 @@ describe("WebMapServiceCatalogItem", function () { }); }); + describe("rectangle - nested groups", () => { + const terria = new Terria(); + const wmsItem = new WebMapServiceCatalogItem("some-layer", terria); + + beforeEach(() => { + runInAction(() => { + wmsItem.setTrait(CommonStrata.definition, "url", "http://example.com"); + wmsItem.setTrait( + CommonStrata.definition, + "getCapabilitiesUrl", + "test/WMS/wms_nested_groups.xml" + ); + }); + }); + + it("correctly uses parent rectangle", async () => { + wmsItem.setTrait( + CommonStrata.definition, + "layers", + "landsat_barest_earth" + ); + + (await wmsItem.loadMetadata()).throwIfError(); + + // This will use the top level EX_GeographicBoundingBox ("Digital Earth Australia - OGC Web Services" Layer) + expect(wmsItem.rectangle.west).toBe(100); + expect(wmsItem.rectangle.east).toBe(160); + expect(wmsItem.rectangle.south).toBe(-50); + expect(wmsItem.rectangle.north).toBe(-10); + }); + }); + it("uses tileWidth and tileHeight", async function () { let wms: WebMapServiceCatalogItem; const terria = new Terria(); diff --git a/wwwroot/test/WMS/wms_nested_groups.xml b/wwwroot/test/WMS/wms_nested_groups.xml index 070a6e8ceef..62a58e44d16 100644 --- a/wwwroot/test/WMS/wms_nested_groups.xml +++ b/wwwroot/test/WMS/wms_nested_groups.xml @@ -1,1175 +1,605 @@ - - - + WMS Digital Earth Australia - OGC Web Services - Digital Earth Australia OGC Web Services - - - - geomedian - - WOfS - - mangrove - - bare-earth - - NIDEM - - HLTC - - landsat - - australia - - time-series - - fractional-cover - + geomedian + WOfS + mangrove + bare-earth + NIDEM + HLTC + landsat + australia + time-series + fractional-cover - - - - - + - - - Digital Earth Australia - Geoscience Australia - - - - - - postal -
GPO Box 378
- Canberra - ACT - 2609 - Australia -
- - - +61 2 6249 9111 - - - - earth.observation@ga.gov.au - + + Digital Earth Australia + Geoscience Australia + + + postal +
GPO Box 378
+ Canberra + ACT + 2609 + Australia +
+ +61 2 6249 9111 + earth.observation@ga.gov.au
- - none © Commonwealth of Australia (Geoscience Australia) 2018. This product is released under the Creative Commons Attribution 4.0 International Licence. http://creativecommons.org/licenses/by/4.0/legalcode - 1 512 512 -
- - +
+ - - text/xml - - - - - - - - - - image/png - - - - - - - - - - application/json - - - - - - - - + + text/xml + + + + + + + + + + image/png + + + + + + + + + + application/json + + + + + + + + - - XML + XML - - - - - Digital Earth Australia - OGC Web Services - - + Digital Earth Australia - OGC Web Services + Digital Earth Australia OGC Web Services - - - - - EPSG:3857 - - EPSG:4326 - - EPSG:3577 - - EPSG:3111 - - - - - - - - + + EPSG:3857 + EPSG:4326 + EPSG:3577 + EPSG:3111 + + 100 + 160 + -50 + -10 + + Surface Reflectance - - - - - - - - - - - - ls8_nbart_geomedian_annual - Surface Reflectance 25m Annual Geomedian (Landsat 8) - + + + ls8_nbart_geomedian_annual + Surface Reflectance 25m Annual Geomedian (Landsat 8) + Data is only visible at higher resolutions; when zoomed-out the available area will be displayed as a shaded region. The surface reflectance geometric median (geomedian) is a pixel composite mosaic of a time series of earth observations. The value of a pixel in a an annual geomedian image is the statistical median of all observations for that pixel from a calendar year. -Annual mosaics are available for the following years: - -Landsat 8: 2013 to 2017; - -For more information, see http://pid.geoscience.gov.au/dataset/ga/120374 - -For service status information, see https://status.dea.ga.gov.au - - - +Annual mosaics are available for the following years:Landsat 8: 2013 to 2017;For more information, see http://pid.geoscience.gov.au/dataset/ga/120374For service status information, see https://status.dea.ga.gov.au + + WOfS - HLTC - landsat - time-series - mangrove - bare-earth - australia - geomedian - NIDEM - fractional-cover - - - + + 109.989859933428 156.101505058599 -45.2413329418709 -9.02727104242042 - - - - - - - - - - - - + + + + + + 2013-01-01,2014-01-01,2015-01-01,2016-01-01,2017-01-01,2018-01-01 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ls7_nbart_geomedian_annual - Surface Reflectance 25m Annual Geomedian (Landsat 7) - + + + + + + + + + + + + + + + ls7_nbart_geomedian_annual + Surface Reflectance 25m Annual Geomedian (Landsat 7) + Data is only visible at higher resolutions; when zoomed-out the available area will be displayed as a shaded region. The surface reflectance geometric median (geomedian) is a pixel composite mosaic of a time series of earth observations. The value of a pixel in a an annual geomedian image is the statistical median of all observations for that pixel from a calendar year. -Annual mosaics are available for the following years: - -Landsat 7: 2000 to 2017; - -For more information, see http://pid.geoscience.gov.au/dataset/ga/120374 - -For service status information, see https://status.dea.ga.gov.au - - - +Annual mosaics are available for the following years:Landsat 7: 2000 to 2017;For more information, see http://pid.geoscience.gov.au/dataset/ga/120374For service status information, see https://status.dea.ga.gov.au + + WOfS - HLTC - landsat - time-series - mangrove - bare-earth - australia - geomedian - NIDEM - fractional-cover - - - + + 109.989859933428 156.101505058599 -45.2413329418709 -9.02727104242042 - - - - - - - - - - - - + + + + + + 2000-01-01,2001-01-01,2002-01-01,2003-01-01,2004-01-01,2005-01-01,2006-01-01,2007-01-01,2008-01-01,2009-01-01,2010-01-01,2011-01-01,2012-01-01,2013-01-01,2014-01-01,2015-01-01,2016-01-01,2017-01-01,2018-01-01 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ls5_nbart_geomedian_annual - Surface Reflectance 25m Annual Geomedian (Landsat 5) - + + + + + + + + + + + + + + + ls5_nbart_geomedian_annual + Surface Reflectance 25m Annual Geomedian (Landsat 5) + Data is only visible at higher resolutions; when zoomed-out the available area will be displayed as a shaded region. The surface reflectance geometric median (geomedian) is a pixel composite mosaic of a time series of earth observations. The value of a pixel in a an annual geomedian image is the statistical median of all observations for that pixel from a calendar year. -Annual mosaics are available for the following years: - -Landsat 5: 1988 to 1999, 2004 to 2007, 2009 to 2011; - -For more information, see http://pid.geoscience.gov.au/dataset/ga/120374 - -For service status information, see https://status.dea.ga.gov.au - - - +Annual mosaics are available for the following years:Landsat 5: 1988 to 1999, 2004 to 2007, 2009 to 2011;For more information, see http://pid.geoscience.gov.au/dataset/ga/120374For service status information, see https://status.dea.ga.gov.au + + WOfS - HLTC - landsat - time-series - mangrove - bare-earth - australia - geomedian - NIDEM - fractional-cover - - - + + 109.989859933428 156.101505058599 -45.2413329418709 -9.02727104242042 - - - - - - - - - - - - + + + + + + 1988-01-01,1989-01-01,1990-01-01,1991-01-01,1992-01-01,1993-01-01,1994-01-01,1995-01-01,1996-01-01,1997-01-01,1998-01-01,1999-01-01,2004-01-01,2005-01-01,2006-01-01,2007-01-01,2009-01-01,2010-01-01,2011-01-01 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + Landsat-8 Barest Earth - - -A `weighted geometric median’ approach has been used to estimate the median surface reflectance of the barest state (i.e., least vegetation) observed through Landsat-8 OLI observations from 2013 to September 2018 to generate a six-band Landsat-8 Barest Earth pixel composite mosaic over the Australian continent. - -The bands include BLUE (0.452 - 0.512), GREEN (0.533 - 0.590), RED, (0.636 - 0.673) NIR (0.851 - 0.879), SWIR1 (1.566 - 1.651) and SWIR2 (2.107 - 2.294) wavelength regions. The weighted median approach is robust to outliers (such as cloud, shadows, saturation, corrupted pixels) and also maintains the relationship between all the spectral wavelengths in the spectra observed through time. The product reduces the influence of vegetation and allows for more direct mapping of soil and rock mineralogy. -Reference: Dale Roberts, John Wilford, and Omar Ghattas (2018). Revealing the Australian Continent at its Barest, submitted. - -Mosaics are available for the following years: +A `weighted geometric median’ approach has been used to estimate the median surface reflectance of the barest state (i.e., least vegetation) observed through Landsat-8 OLI observations from 2013 to September 2018 to generate a six-band Landsat-8 Barest Earth pixel composite mosaic over the Australian continent.The bands include BLUE (0.452 - 0.512), GREEN (0.533 - 0.590), RED, (0.636 - 0.673) NIR (0.851 - 0.879), SWIR1 (1.566 - 1.651) and SWIR2 (2.107 - 2.294) wavelength regions. The weighted median approach is robust to outliers (such as cloud, shadows, saturation, corrupted pixels) and also maintains the relationship between all the spectral wavelengths in the spectra observed through time. The product reduces the influence of vegetation and allows for more direct mapping of soil and rock mineralogy.Reference: Dale Roberts, John Wilford, and Omar Ghattas (2018). Revealing the Australian Continent at its Barest, submitted.Mosaics are available for the following years: Landsat 8: 2013 to 2017; - - - - - - - - - - ls8_barest_earth_mosaic - Landsat-8 Barest Earth 25m albers (Landsat-8) - -A `weighted geometric median’ approach has been used to estimate the median surface reflectance of the barest state (i.e., least vegetation) observed through Landsat-8 OLI observations from 2013 to September 2018 to generate a six-band Landsat-8 Barest Earth pixel composite mosaic over the Australian continent. -The bands include BLUE (0.452 - 0.512), GREEN (0.533 - 0.590), RED, (0.636 - 0.673) NIR (0.851 - 0.879), SWIR1 (1.566 - 1.651) and SWIR2 (2.107 - 2.294) wavelength regions. The weighted median approach is robust to outliers (such as cloud, shadows, saturation, corrupted pixels) and also maintains the relationship between all the spectral wavelengths in the spectra observed through time. The product reduces the influence of vegetation and allows for more direct mapping of soil and rock mineralogy. - -Reference: Dale Roberts, John Wilford, and Omar Ghattas (2018). Revealing the Australian Continent at its Barest, submitted. - -Mosaics are available for the following years: - Landsat 8: 2013 to 2017; - -For service status information, see https://status.dea.ga.gov.au - - - + + + ls8_barest_earth_mosaic + Landsat-8 Barest Earth 25m albers (Landsat-8) + +A `weighted geometric median’ approach has been used to estimate the median surface reflectance of the barest state (i.e., least vegetation) observed through Landsat-8 OLI observations from 2013 to September 2018 to generate a six-band Landsat-8 Barest Earth pixel composite mosaic over the Australian continent.The bands include BLUE (0.452 - 0.512), GREEN (0.533 - 0.590), RED, (0.636 - 0.673) NIR (0.851 - 0.879), SWIR1 (1.566 - 1.651) and SWIR2 (2.107 - 2.294) wavelength regions. The weighted median approach is robust to outliers (such as cloud, shadows, saturation, corrupted pixels) and also maintains the relationship between all the spectral wavelengths in the spectra observed through time. The product reduces the influence of vegetation and allows for more direct mapping of soil and rock mineralogy.Reference: Dale Roberts, John Wilford, and Omar Ghattas (2018). Revealing the Australian Continent at its Barest, submitted.Mosaics are available for the following years: + Landsat 8: 2013 to 2017;For service status information, see https://status.dea.ga.gov.au + + WOfS - HLTC - landsat - time-series - mangrove - bare-earth - australia - geomedian - NIDEM - fractional-cover - - - + + 109.989859933428 156.101505058599 -45.2413329418709 -9.02727104242042 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + Landsat 30+ Barest Earth - - -An estimate of the spectra of the barest state (i.e., least vegetation) observed from imagery of the Australian continent collected by the Landsat 5, 7, and 8 satellites over a period of more than 30 years (1983 - 2018). The bands include BLUE (0.452 - 0.512), GREEN (0.533 - 0.590), RED, (0.636 - 0.673) NIR (0.851 - 0.879), SWIR1 (1.566 - 1.651) and SWIR2 (2.107 - 2.294) wavelength regions. The approach is robust to outliers (such as cloud, shadows, saturation, corrupted pixels) and also maintains the relationship between all the spectral wavelengths in the spectra observed through time. The product reduces the influence of vegetation and allows for more direct mapping of soil and rock mineralogy. This product complements the Landsat-8 Barest Earth which is based on the same algorithm but just uses Landsat8 satellite imagery from 2013-2108. Landsat-8's OLI sensor provides improved signal-to-noise radiometric (SNR) performance quantised over a 12-bit dynamic range compared to the 8-bit dynamic range of Landsat-5 and Landsat-7 data. However the Landsat 30+ Barest Earth has a greater capacity to find the barest ground due to the greater temporal depth. Reference: Roberts, D., Wilford, J., Ghattas, O. (2019). Exposed Soil and Mineral Map of the Australian Continent Revealing the Land at its Barest. Nature Communications. Mosaics are available for the following years: Landsat 5 / Landsat 7 / Landsat 8 - 1983 to 2018; - +An estimate of the spectra of the barest state (i.e., least vegetation) observed from imagery of the Australian continent collected by the Landsat 5, 7, and 8 satellites over a period of more than 30 years (1983 - 2018). The bands include BLUE (0.452 - 0.512), GREEN (0.533 - 0.590), RED, (0.636 - 0.673) NIR (0.851 - 0.879), SWIR1 (1.566 - 1.651) and SWIR2 (2.107 - 2.294) wavelength regions. The approach is robust to outliers (such as cloud, shadows, saturation, corrupted pixels) and also maintains the relationship between all the spectral wavelengths in the spectra observed through time. The product reduces the influence of vegetation and allows for more direct mapping of soil and rock mineralogy. This product complements the Landsat-8 Barest Earth which is based on the same algorithm but just uses Landsat8 satellite imagery from 2013-2108. Landsat-8's OLI sensor provides improved signal-to-noise radiometric (SNR) performance quantised over a 12-bit dynamic range compared to the 8-bit dynamic range of Landsat-5 and Landsat-7 data. However the Landsat 30+ Barest Earth has a greater capacity to find the barest ground due to the greater temporal depth. Reference: Roberts, D., Wilford, J., Ghattas, O. (2019). Exposed Soil and Mineral Map of the Australian Continent Revealing the Land at its Barest. Nature Communications. Mosaics are available for the following years: Landsat 5 / Landsat 7 / Landsat 8 - 1983 to 2018; - - - - - - - - landsat_barest_earth - Landsat 30+ Barest Earth 25m albers (Combined Landsat) - -An estimate of the spectra of the barest state (i.e., least vegetation) observed from imagery of the Australian continent collected by the Landsat 5, 7, and 8 satellites over a period of more than 30 years (1983 - 2018). -The bands include BLUE (0.452 - 0.512), GREEN (0.533 - 0.590), RED, (0.636 - 0.673) NIR (0.851 - 0.879), SWIR1 (1.566 - 1.651) and SWIR2 (2.107 - 2.294) wavelength regions. The approach is robust to outliers (such as cloud, shadows, saturation, corrupted pixels) and also maintains the relationship between all the spectral wavelengths in the spectra observed through time. The product reduces the influence of vegetation and allows for more direct mapping of soil and rock mineralogy. -This product complements the Landsat-8 Barest Earth which is based on the same algorithm but just uses Landsat8 satellite imagery from 2013-2108. Landsat-8's OLI sensor provides improved signal-to-noise radiometric (SNR) performance quantised over a 12-bit dynamic range compared to the 8-bit dynamic range of Landsat-5 and Landsat-7 data. However the Landsat 30+ Barest Earth has a greater capacity to find the barest ground due to the greater temporal depth. -Reference: Roberts, D., Wilford, J., Ghattas, O. (2019). Exposed Soil and Mineral Map of the Australian Continent Revealing the Land at its Barest. Nature Communications. Mosaics are available for the following years: Landsat 5 / Landsat 7 / Landsat 8 - 1983 to 2018; For service status information, see https://status.dea.ga.gov.au - - - + + landsat_barest_earth + Landsat 30+ Barest Earth 25m albers (Combined Landsat) + +NOTE this layer has no EX_GeographicBoundingBox + + WOfS - HLTC - landsat - time-series - mangrove - bare-earth - australia - geomedian - NIDEM - fractional-cover - - - - 109.989859933428 - 156.101505058599 - -45.2413329418709 - -9.02727104242042 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - - - - - - - - - -
\ No newline at end of file + + From 5c595f0ded9361c345f21309775c8d8a97fc6e56 Mon Sep 17 00:00:00 2001 From: Zoran Kokeza Date: Mon, 11 Sep 2023 13:34:13 +0200 Subject: [PATCH 13/15] fix: update changelog --- CHANGES.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 3b63f86bd20..ee136b60633 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,6 +2,8 @@ #### next release (8.3.4) +- Move map credits to map column so it don't get hidden by chart panel +- TSify `MapColumn` module and reorganize components directory structure. - [The next improvement] #### next release (8.3.3) @@ -10,7 +12,6 @@ - Fixed rectangle drawing in 2D mode. - Added EPSG:7855 to `Proj4Definitions`. - Fix multi level nesting in ArcGIS Mapserver. -- [The next improvement] #### 8.3.2 - 2023-08-11 @@ -253,8 +254,6 @@ - Fix `SearchBoxAndResults` Trans values - Fix `generateCatalogIndex` for nested references - Fix `SearchBox` handling of `searchWithDebounce` when `debounceDuration` prop changes. It now fushes instead of cancels. -- Move map credits to map column so it don't get hidden by chart panel -- [The next improvement] #### 8.2.10 - 2022-08-02 From a88d20ecab80f2ca0374a5cfc2dbd443e8d782a2 Mon Sep 17 00:00:00 2001 From: Nick Forbes-Smith Date: Tue, 12 Sep 2023 13:36:31 +1000 Subject: [PATCH 14/15] Remove unnecessary optional chaining --- lib/Models/Catalog/Ows/WebMapServiceCapabilities.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/Models/Catalog/Ows/WebMapServiceCapabilities.ts b/lib/Models/Catalog/Ows/WebMapServiceCapabilities.ts index 804308108b0..bffbafb677a 100644 --- a/lib/Models/Catalog/Ows/WebMapServiceCapabilities.ts +++ b/lib/Models/Catalog/Ows/WebMapServiceCapabilities.ts @@ -132,7 +132,7 @@ type Mutable = { -readonly [P in keyof T]: T[P] }; export function getRectangleFromLayer( layer: CapabilitiesLayer ): StratumFromTraits | undefined { - var egbb = layer?.EX_GeographicBoundingBox; // required in WMS 1.3.0 + var egbb = layer.EX_GeographicBoundingBox; // required in WMS 1.3.0 if (egbb) { return { west: egbb.westBoundLongitude, @@ -141,7 +141,7 @@ export function getRectangleFromLayer( north: egbb.northBoundLatitude }; } else { - var llbb = layer?.LatLonBoundingBox; // required in WMS 1.0.0 through 1.1.1 + var llbb = layer.LatLonBoundingBox; // required in WMS 1.0.0 through 1.1.1 if (llbb) { return { west: llbb.minx, @@ -153,7 +153,7 @@ export function getRectangleFromLayer( } // Work way through ancestors until we get a rectangle. - if (layer?._parent) return getRectangleFromLayer(layer._parent); + if (layer._parent) return getRectangleFromLayer(layer._parent); return undefined; } From be3987693d7537b8c2a21d2e308db9876e606a1d Mon Sep 17 00:00:00 2001 From: Nick Forbes-Smith Date: Tue, 12 Sep 2023 13:37:02 +1000 Subject: [PATCH 15/15] update CHANGES --- CHANGES.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 107cb88cadb..b4688010dc5 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -4,6 +4,7 @@ - Move map credits to map column so it don't get hidden by chart panel - TSify `MapColumn` module and reorganize components directory structure. +- Add null check to `WebMapServiceCatalogItem` `rectangle` calculation - and now we ascend tree of WMS `Layers` until we find a rectangle. - [The next improvement] #### next release (8.3.3) @@ -11,8 +12,6 @@ - Fixed broken point dragging interaction for user drawing in 3D mode. - Fixed rectangle drawing in 2D mode. - Added EPSG:7855 to `Proj4Definitions`. -- Add null check to `WebMapServiceCatalogItem` `rectangle` calculation - and now we ascend tree of WMS `Layers` until we find a rectangle. -- [The next improvement] - Fix multi level nesting in ArcGIS Mapserver. #### 8.3.2 - 2023-08-11