| 
									
										
										
										
											2021-10-15 05:20:02 +02:00
										 |  |  | import FeaturePipelineState from "../Logic/State/FeaturePipelineState"; | 
					
						
							|  |  |  | import State from "../State"; | 
					
						
							|  |  |  | import {Utils} from "../Utils"; | 
					
						
							|  |  |  | import {UIEventSource} from "../Logic/UIEventSource"; | 
					
						
							|  |  |  | import FullWelcomePaneWithTabs from "./BigComponents/FullWelcomePaneWithTabs"; | 
					
						
							|  |  |  | import MapControlButton from "./MapControlButton"; | 
					
						
							|  |  |  | import Svg from "../Svg"; | 
					
						
							|  |  |  | import Toggle from "./Input/Toggle"; | 
					
						
							|  |  |  | import UserBadge from "./BigComponents/UserBadge"; | 
					
						
							|  |  |  | import SearchAndGo from "./BigComponents/SearchAndGo"; | 
					
						
							|  |  |  | import Link from "./Base/Link"; | 
					
						
							|  |  |  | import BaseUIElement from "./BaseUIElement"; | 
					
						
							|  |  |  | import {VariableUiElement} from "./Base/VariableUIElement"; | 
					
						
							|  |  |  | import LeftControls from "./BigComponents/LeftControls"; | 
					
						
							|  |  |  | import RightControls from "./BigComponents/RightControls"; | 
					
						
							|  |  |  | import CenterMessageBox from "./CenterMessageBox"; | 
					
						
							| 
									
										
										
										
											2021-10-15 14:52:11 +02:00
										 |  |  | import ShowDataLayer from "./ShowDataLayer/ShowDataLayer"; | 
					
						
							|  |  |  | import AllKnownLayers from "../Customizations/AllKnownLayers"; | 
					
						
							|  |  |  | import ScrollableFullScreen from "./Base/ScrollableFullScreen"; | 
					
						
							|  |  |  | import Translations from "./i18n/Translations"; | 
					
						
							|  |  |  | import SimpleAddUI from "./BigComponents/SimpleAddUI"; | 
					
						
							|  |  |  | import StrayClickHandler from "../Logic/Actors/StrayClickHandler"; | 
					
						
							| 
									
										
										
										
											2021-10-20 01:13:55 +02:00
										 |  |  | import Lazy from "./Base/Lazy"; | 
					
						
							| 
									
										
										
										
											2021-11-03 00:44:53 +01:00
										 |  |  | import {DefaultGuiState} from "./DefaultGuiState"; | 
					
						
							| 
									
										
										
										
											2021-10-15 05:20:02 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * The default MapComplete GUI initializor | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Adds a welcome pane, contorl buttons, ... etc to index.html | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | export default class DefaultGUI { | 
					
						
							|  |  |  |     private readonly _guiState: DefaultGuiState; | 
					
						
							|  |  |  |     private readonly state: FeaturePipelineState; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     constructor(state: FeaturePipelineState, guiState: DefaultGuiState) { | 
					
						
							|  |  |  |         this.state = state; | 
					
						
							|  |  |  |         this._guiState = guiState; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (state.layoutToUse.customCss !== undefined) { | 
					
						
							|  |  |  |             Utils.LoadCustomCss(state.layoutToUse.customCss); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-20 01:13:55 +02:00
										 |  |  |         this.SetupUIElements(); | 
					
						
							|  |  |  |         this.SetupMap() | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private SetupMap(){ | 
					
						
							|  |  |  |         const state = this.state; | 
					
						
							|  |  |  |         const guiState = this._guiState; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-15 05:20:02 +02:00
										 |  |  |         // Attach the map
 | 
					
						
							|  |  |  |         state.mainMapObject.SetClass("w-full h-full") | 
					
						
							|  |  |  |             .AttachTo("leafletDiv") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-15 14:52:11 +02:00
										 |  |  |         this.setupClickDialogOnMap( | 
					
						
							| 
									
										
										
										
											2021-10-15 05:20:02 +02:00
										 |  |  |             guiState.filterViewIsOpened, | 
					
						
							| 
									
										
										
										
											2021-10-15 14:52:11 +02:00
										 |  |  |             state | 
					
						
							| 
									
										
										
										
											2021-10-15 05:20:02 +02:00
										 |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-20 01:13:55 +02:00
										 |  |  |         new ShowDataLayer({ | 
					
						
							|  |  |  |             leafletMap: state.leafletMap, | 
					
						
							|  |  |  |             layerToShow: AllKnownLayers.sharedLayers.get("home_location"), | 
					
						
							|  |  |  |             features: state.homeLocation, | 
					
						
							|  |  |  |             enablePopups: false, | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         state.leafletMap.addCallbackAndRunD(_ => { | 
					
						
							|  |  |  |             // Lets assume that all showDataLayers are initialized at this point
 | 
					
						
							|  |  |  |             state.selectedElement.ping() | 
					
						
							|  |  |  |             State.state.locationControl.ping(); | 
					
						
							|  |  |  |             return true; | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     private SetupUIElements(){ | 
					
						
							|  |  |  |         const state = this.state; | 
					
						
							|  |  |  |         const guiState = this._guiState; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const self =this | 
					
						
							| 
									
										
										
										
											2021-10-15 05:20:02 +02:00
										 |  |  |         Toggle.If(state.featureSwitchUserbadge, | 
					
						
							|  |  |  |             () => new UserBadge(state) | 
					
						
							|  |  |  |         ).AttachTo("userbadge") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Toggle.If(state.featureSwitchSearch, | 
					
						
							|  |  |  |             () => new SearchAndGo(state)) | 
					
						
							|  |  |  |             .AttachTo("searchbox"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         let iframePopout: () => BaseUIElement = undefined; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (window !== window.top) { | 
					
						
							|  |  |  |             // MapComplete is running in an iframe
 | 
					
						
							|  |  |  |             iframePopout = () => new VariableUiElement(state.locationControl.map(loc => { | 
					
						
							|  |  |  |                 const url = `${window.location.origin}${window.location.pathname}?z=${loc.zoom ?? 0}&lat=${loc.lat ?? 0}&lon=${loc.lon ?? 0}`; | 
					
						
							|  |  |  |                 const link = new Link(Svg.pop_out_img, url, true).SetClass("block w-full h-full p-1.5") | 
					
						
							|  |  |  |                 return new MapControlButton(link) | 
					
						
							|  |  |  |             })) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-20 01:13:55 +02:00
										 |  |  |         new Toggle(new Lazy(() => self.InitWelcomeMessage()), | 
					
						
							|  |  |  |             Toggle.If(state.featureSwitchIframePopoutEnabled, iframePopout), | 
					
						
							| 
									
										
										
										
											2021-10-15 05:20:02 +02:00
										 |  |  |             state.featureSwitchWelcomeMessage | 
					
						
							|  |  |  |         ).AttachTo("messagesbox"); | 
					
						
							| 
									
										
										
										
											2021-10-23 02:46:37 +02:00
										 |  |  |          | 
					
						
							| 
									
										
										
										
											2021-10-15 05:20:02 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         new LeftControls(state, guiState).AttachTo("bottom-left"); | 
					
						
							|  |  |  |         new RightControls(state).AttachTo("bottom-right"); | 
					
						
							| 
									
										
										
										
											2021-10-20 01:13:55 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-15 05:20:02 +02:00
										 |  |  |         new CenterMessageBox(state).AttachTo("centermessage"); | 
					
						
							|  |  |  |         document | 
					
						
							|  |  |  |             .getElementById("centermessage") | 
					
						
							|  |  |  |             .classList.add("pointer-events-none"); | 
					
						
							| 
									
										
										
										
											2021-10-23 02:46:37 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // We have to ping the welcomeMessageIsOpened and other isOpened-stuff to activate the FullScreenMessage if needed
 | 
					
						
							|  |  |  |         for (const state of guiState.allFullScreenStates) { | 
					
						
							|  |  |  |             if(state.data){ | 
					
						
							|  |  |  |                 state.ping() | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /** | 
					
						
							|  |  |  |          * At last, if the map moves or an element is selected, we close all the panels just as well | 
					
						
							|  |  |  |          */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         state.selectedElement.addCallbackAndRunD((_) => { | 
					
						
							|  |  |  |             guiState.allFullScreenStates.forEach(s => s.setData(false)) | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2021-10-15 05:20:02 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-20 01:13:55 +02:00
										 |  |  |     private InitWelcomeMessage() : BaseUIElement{ | 
					
						
							| 
									
										
										
										
											2021-10-15 05:20:02 +02:00
										 |  |  |         const isOpened = this._guiState.welcomeMessageIsOpened | 
					
						
							|  |  |  |         const fullOptions = new FullWelcomePaneWithTabs(isOpened, this._guiState.welcomeMessageOpenedTab, this.state); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // ?-Button on Desktop, opens panel with close-X.
 | 
					
						
							|  |  |  |         const help = new MapControlButton(Svg.help_svg()); | 
					
						
							|  |  |  |         help.onClick(() => isOpened.setData(true)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const openedTime = new Date().getTime(); | 
					
						
							|  |  |  |         this.state.locationControl.addCallback(() => { | 
					
						
							|  |  |  |             if (new Date().getTime() - openedTime < 15 * 1000) { | 
					
						
							|  |  |  |                 // Don't autoclose the first 15 secs when the map is moving
 | 
					
						
							|  |  |  |                 return; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             isOpened.setData(false); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         this.state.selectedElement.addCallbackAndRunD((_) => { | 
					
						
							|  |  |  |             isOpened.setData(false); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return new Toggle( | 
					
						
							|  |  |  |             fullOptions.SetClass("welcomeMessage pointer-events-auto"), | 
					
						
							|  |  |  |             help.SetClass("pointer-events-auto"), | 
					
						
							|  |  |  |             isOpened | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-15 14:52:11 +02:00
										 |  |  |     public setupClickDialogOnMap(filterViewIsOpened: UIEventSource<boolean>, state: FeaturePipelineState) { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-20 01:13:55 +02:00
										 |  |  |         function setup() { | 
					
						
							| 
									
										
										
										
											2021-10-15 14:52:11 +02:00
										 |  |  |             let presetCount = 0; | 
					
						
							|  |  |  |             for (const layer of state.layoutToUse.layers) { | 
					
						
							|  |  |  |                 for (const preset of layer.presets) { | 
					
						
							|  |  |  |                     presetCount++; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             if (presetCount == 0) { | 
					
						
							|  |  |  |                 return; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             const newPointDialogIsShown = new UIEventSource<boolean>(false); | 
					
						
							|  |  |  |             const addNewPoint = new ScrollableFullScreen( | 
					
						
							|  |  |  |                 () => Translations.t.general.add.title.Clone(), | 
					
						
							|  |  |  |                 () => new SimpleAddUI(newPointDialogIsShown, filterViewIsOpened, state), | 
					
						
							| 
									
										
										
										
											2021-10-25 20:50:59 +02:00
										 |  |  |                 "new", | 
					
						
							| 
									
										
										
										
											2021-10-15 14:52:11 +02:00
										 |  |  |                 newPointDialogIsShown | 
					
						
							|  |  |  |             ); | 
					
						
							|  |  |  |             addNewPoint.isShown.addCallback((isShown) => { | 
					
						
							|  |  |  |                 if (!isShown) { | 
					
						
							|  |  |  |                     state.LastClickLocation.setData(undefined); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             new StrayClickHandler( | 
					
						
							|  |  |  |                 state.LastClickLocation, | 
					
						
							|  |  |  |                 state.selectedElement, | 
					
						
							|  |  |  |                 state.filteredLayers, | 
					
						
							|  |  |  |                 state.leafletMap, | 
					
						
							|  |  |  |                 addNewPoint | 
					
						
							|  |  |  |             ); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         state.featureSwitchAddNew.addCallbackAndRunD(addNewAllowed => { | 
					
						
							|  |  |  |             if (addNewAllowed) { | 
					
						
							|  |  |  |                 setup() | 
					
						
							|  |  |  |                 return true; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-15 05:20:02 +02:00
										 |  |  | } |