forked from MapComplete/MapComplete
		
	refactoring: Remove more obsoleted code, add copyright tab
This commit is contained in:
		
							parent
							
								
									f8d34648a0
								
							
						
					
					
						commit
						042d400dc4
					
				
					 20 changed files with 44 additions and 342 deletions
				
			
		|  | @ -1,25 +0,0 @@ | ||||||
| import { UIEventSource } from "../UIEventSource" |  | ||||||
| import FilteredLayer from "../../Models/FilteredLayer" |  | ||||||
| import ScrollableFullScreen from "../../UI/Base/ScrollableFullScreen" |  | ||||||
| import BaseUIElement from "../../UI/BaseUIElement" |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * The stray-click-handler adds a marker to the map if no feature was clicked. |  | ||||||
|  * Shows the given uiToShow-element in the messagebox |  | ||||||
|  * |  | ||||||
|  * Note: the actual implementation is in StrayClickHandlerImplementation |  | ||||||
|  */ |  | ||||||
| export default class StrayClickHandler { |  | ||||||
|     public static construct = ( |  | ||||||
|         state: { |  | ||||||
|             LastClickLocation: UIEventSource<{ lat: number; lon: number }> |  | ||||||
|             selectedElement: UIEventSource<string> |  | ||||||
|             filteredLayers: UIEventSource<FilteredLayer[]> |  | ||||||
|             leafletMap: UIEventSource<any> |  | ||||||
|         }, |  | ||||||
|         uiToShow: ScrollableFullScreen, |  | ||||||
|         iconToShow: BaseUIElement |  | ||||||
|     ) => { |  | ||||||
|         return undefined |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  | @ -11,13 +11,13 @@ export default class ContributorCount { | ||||||
|     private lastUpdate: Date = undefined |     private lastUpdate: Date = undefined | ||||||
| 
 | 
 | ||||||
|     constructor(state: { |     constructor(state: { | ||||||
|         bounds: Store<BBox> |         mapProperties: { bounds: Store<BBox> } | ||||||
|         dataIsLoading: Store<boolean> |         dataIsLoading: Store<boolean> | ||||||
|         perLayer: ReadonlyMap<string, GeoIndexedStore> |         perLayer: ReadonlyMap<string, GeoIndexedStore> | ||||||
|     }) { |     }) { | ||||||
|         this.perLayer = state.perLayer |         this.perLayer = state.perLayer | ||||||
|         const self = this |         const self = this | ||||||
|         state.bounds.mapD( |         state.mapProperties.bounds.mapD( | ||||||
|             (bbox) => { |             (bbox) => { | ||||||
|                 self.update(bbox) |                 self.update(bbox) | ||||||
|             }, |             }, | ||||||
|  |  | ||||||
|  | @ -1,4 +1,4 @@ | ||||||
| import { FeatureSource , FeatureSourceForLayer } from "../FeatureSource" | import { FeatureSource, FeatureSourceForLayer } from "../FeatureSource" | ||||||
| import { Feature } from "geojson" | import { Feature } from "geojson" | ||||||
| import { BBox } from "../../BBox" | import { BBox } from "../../BBox" | ||||||
| import { GeoOperations } from "../../GeoOperations" | import { GeoOperations } from "../../GeoOperations" | ||||||
|  | @ -26,9 +26,12 @@ export default class GeoIndexedStore implements FeatureSource { | ||||||
|     public GetFeaturesWithin(bbox: BBox): Feature[] { |     public GetFeaturesWithin(bbox: BBox): Feature[] { | ||||||
|         // TODO optimize
 |         // TODO optimize
 | ||||||
|         const bboxFeature = bbox.asGeoJson({}) |         const bboxFeature = bbox.asGeoJson({}) | ||||||
|         return this.features.data.filter( |         return this.features.data.filter((f) => { | ||||||
|             (f) => GeoOperations.intersect(f, bboxFeature) !== undefined |             if (f.geometry.type === "Point") { | ||||||
|         ) |                 return bbox.contains(<[number, number]>f.geometry.coordinates) | ||||||
|  |             } | ||||||
|  |             return GeoOperations.intersect(f, bboxFeature) !== undefined | ||||||
|  |         }) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,17 +0,0 @@ | ||||||
| import SelectedFeatureHandler from "../Actors/SelectedFeatureHandler" |  | ||||||
| import Hash from "../Web/Hash" |  | ||||||
| import MetaTagRecalculator from "../FeatureSource/Actors/MetaTagRecalculator" |  | ||||||
| 
 |  | ||||||
| export default class FeaturePipelineState { |  | ||||||
|     /** |  | ||||||
|      * The piece of code which fetches data from various sources and shows it on the background map |  | ||||||
|      */ |  | ||||||
|     public readonly featurePipeline: FeaturePipeline |  | ||||||
|     private readonly metatagRecalculator: MetaTagRecalculator |  | ||||||
| 
 |  | ||||||
|     constructor() { |  | ||||||
|         this.metatagRecalculator = new MetaTagRecalculator(this, this.featurePipeline) |  | ||||||
|         this.metatagRecalculator.registerSource(this.currentView) |  | ||||||
|         new SelectedFeatureHandler(Hash.hash, this) |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  | @ -244,7 +244,7 @@ export class RegexTag extends TagsFilter { | ||||||
|         return [] |         return [] | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     asChange(properties: Record<string, string>): { k: string; v: string }[] { |     asChange(): { k: string; v: string }[] { | ||||||
|         if (this.invert) { |         if (this.invert) { | ||||||
|             return [] |             return [] | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  | @ -222,6 +222,14 @@ export default class ThemeViewState implements SpecialVisualizationState { | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         ) |         ) | ||||||
|  |         /* | ||||||
|  |         Hotkeys.RegisterHotkey( | ||||||
|  |             { shift: "O" }, | ||||||
|  |             Translations.t.hotkeyDocumentation.selectMapnik, | ||||||
|  |             () => { | ||||||
|  |                 this.state.backgroundLayer.setData(AvailableBaseLayers.osmCarto) | ||||||
|  |             } | ||||||
|  |         )//*/
 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|  |  | ||||||
|  | @ -107,9 +107,6 @@ export default class ScrollableFullScreen { | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     Destroy() { |  | ||||||
|         this._fullscreencomponent.Destroy() |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Actually show this in the 'fullscreen'-div |      * Actually show this in the 'fullscreen'-div | ||||||
|  | @ -163,7 +160,4 @@ export default class ScrollableFullScreen { | ||||||
|         ) |         ) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     static ActivateCurrent() { |  | ||||||
|         ScrollableFullScreen._currentlyOpen?.Activate() |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -5,6 +5,9 @@ import BaseUIElement from "../BaseUIElement" | ||||||
| import { VariableUiElement } from "./VariableUIElement" | import { VariableUiElement } from "./VariableUIElement" | ||||||
| 
 | 
 | ||||||
| export class TabbedComponent extends Combine { | export class TabbedComponent extends Combine { | ||||||
|  |     /** | ||||||
|  |      * @deprecated | ||||||
|  |      */ | ||||||
|     constructor( |     constructor( | ||||||
|         elements: { header: BaseUIElement | string; content: BaseUIElement | string }[], |         elements: { header: BaseUIElement | string; content: BaseUIElement | string }[], | ||||||
|         openedTab: UIEventSource<number> | number = 0, |         openedTab: UIEventSource<number> | number = 0, | ||||||
|  |  | ||||||
|  | @ -113,7 +113,7 @@ export default class CopyrightPanel extends Combine { | ||||||
| 
 | 
 | ||||||
|     constructor(state: { |     constructor(state: { | ||||||
|         layout: LayoutConfig |         layout: LayoutConfig | ||||||
|         bounds: Store<BBox> |         mapProperties: { bounds: Store<BBox> } | ||||||
|         osmConnection: OsmConnection |         osmConnection: OsmConnection | ||||||
|         dataIsLoading: Store<boolean> |         dataIsLoading: Store<boolean> | ||||||
|         perLayer: ReadonlyMap<string, GeoIndexedStore> |         perLayer: ReadonlyMap<string, GeoIndexedStore> | ||||||
|  | @ -121,7 +121,7 @@ export default class CopyrightPanel extends Combine { | ||||||
|         const t = Translations.t.general.attribution |         const t = Translations.t.general.attribution | ||||||
|         const layoutToUse = state.layout |         const layoutToUse = state.layout | ||||||
| 
 | 
 | ||||||
|         const iconAttributions: BaseUIElement[] = layoutToUse.usedImages.map( |         const iconAttributions: BaseUIElement[] = Utils.Dedup(layoutToUse.usedImages).map( | ||||||
|             CopyrightPanel.IconAttribution |             CopyrightPanel.IconAttribution | ||||||
|         ) |         ) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -38,7 +38,7 @@ | ||||||
|     fieldTypes[field.name + "}"] = field.type; |     fieldTypes[field.name + "}"] = field.type; | ||||||
|     const src = new UIEventSource<string>(initialState[field.name] ?? ""); |     const src = new UIEventSource<string>(initialState[field.name] ?? ""); | ||||||
|     fieldValues[field.name + "}"] = src; |     fieldValues[field.name + "}"] = src; | ||||||
|     onDestroy(src.addCallback(v => { |     onDestroy(src.addCallback(() => { | ||||||
|       setFields(); |       setFields(); | ||||||
|     })); |     })); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  | @ -1,131 +0,0 @@ | ||||||
| import ThemeIntroductionPanel from "./ThemeIntroductionPanel" |  | ||||||
| import Svg from "../../Svg" |  | ||||||
| import Translations from "../i18n/Translations" |  | ||||||
| import ShareScreen from "./ShareScreen" |  | ||||||
| import MoreScreen from "./MoreScreen" |  | ||||||
| import Constants from "../../Models/Constants" |  | ||||||
| import Combine from "../Base/Combine" |  | ||||||
| import { TabbedComponent } from "../Base/TabbedComponent" |  | ||||||
| import { UIEventSource } from "../../Logic/UIEventSource" |  | ||||||
| import UserDetails, { OsmConnection } from "../../Logic/Osm/OsmConnection" |  | ||||||
| import ScrollableFullScreen from "../Base/ScrollableFullScreen" |  | ||||||
| import BaseUIElement from "../BaseUIElement" |  | ||||||
| import Toggle from "../Input/Toggle" |  | ||||||
| import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig" |  | ||||||
| import { Utils } from "../../Utils" |  | ||||||
| import UserRelatedState from "../../Logic/State/UserRelatedState" |  | ||||||
| import Loc from "../../Models/Loc" |  | ||||||
| import FilteredLayer from "../../Models/FilteredLayer" |  | ||||||
| import Hotkeys from "../Base/Hotkeys" |  | ||||||
| 
 |  | ||||||
| export default class FullWelcomePaneWithTabs extends ScrollableFullScreen { |  | ||||||
|     public static MoreThemesTabIndex = 1 |  | ||||||
| 
 |  | ||||||
|     constructor( |  | ||||||
|         isShown: UIEventSource<boolean>, |  | ||||||
|         currentTab: UIEventSource<number>, |  | ||||||
|         state: { |  | ||||||
|             layoutToUse: LayoutConfig |  | ||||||
|             osmConnection: OsmConnection |  | ||||||
|             featureSwitchShareScreen: UIEventSource<boolean> |  | ||||||
|             featureSwitchMoreQuests: UIEventSource<boolean> |  | ||||||
|             locationControl: UIEventSource<Loc> |  | ||||||
|             featurePipeline: FeaturePipeline |  | ||||||
|             backgroundLayer: UIEventSource<BaseLayer> |  | ||||||
|             filteredLayers: UIEventSource<FilteredLayer[]> |  | ||||||
|         } & UserRelatedState, |  | ||||||
|         guistate?: { userInfoIsOpened: UIEventSource<boolean> } |  | ||||||
|     ) { |  | ||||||
|         const layoutToUse = state.layoutToUse |  | ||||||
|         super( |  | ||||||
|             () => layoutToUse.title.Clone(), |  | ||||||
|             () => FullWelcomePaneWithTabs.GenerateContents(state, currentTab, isShown, guistate), |  | ||||||
|             "welcome", |  | ||||||
|             isShown |  | ||||||
|         ) |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private static ConstructBaseTabs( |  | ||||||
|         state: { |  | ||||||
|             layoutToUse: LayoutConfig |  | ||||||
|             osmConnection: OsmConnection |  | ||||||
|             featureSwitchShareScreen: UIEventSource<boolean> |  | ||||||
|             featureSwitchMoreQuests: UIEventSource<boolean> |  | ||||||
|             featurePipeline: FeaturePipeline |  | ||||||
|             locationControl: UIEventSource<Loc> |  | ||||||
|             backgroundLayer: UIEventSource<BaseLayer> |  | ||||||
|             filteredLayers: UIEventSource<FilteredLayer[]> |  | ||||||
|         } & UserRelatedState, |  | ||||||
|         isShown: UIEventSource<boolean>, |  | ||||||
|         currentTab: UIEventSource<number>, |  | ||||||
|         guistate?: { userInfoIsOpened: UIEventSource<boolean> } |  | ||||||
|     ): { header: string | BaseUIElement; content: BaseUIElement }[] { |  | ||||||
|         const tabs: { header: string | BaseUIElement; content: BaseUIElement }[] = [ |  | ||||||
|             { |  | ||||||
|                 header: `<img src='${state.layoutToUse.icon}'>`, |  | ||||||
|                 content: new ThemeIntroductionPanel(isShown, currentTab, state, guistate), |  | ||||||
|             }, |  | ||||||
|         ] |  | ||||||
| 
 |  | ||||||
|         if (state.featureSwitchMoreQuests.data) { |  | ||||||
|             tabs.push({ |  | ||||||
|                 header: Svg.add_img, |  | ||||||
|                 content: new Combine([ |  | ||||||
|                     Translations.t.general.morescreen.intro, |  | ||||||
|                     new MoreScreen(state), |  | ||||||
|                 ]).SetClass("flex flex-col"), |  | ||||||
|             }) |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (state.featureSwitchShareScreen.data) { |  | ||||||
|             tabs.push({ header: Svg.share_img, content: new ShareScreen(state) }) |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return tabs |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private static GenerateContents( |  | ||||||
|         state: { |  | ||||||
|             layoutToUse: LayoutConfig |  | ||||||
|             osmConnection: OsmConnection |  | ||||||
|             featureSwitchShareScreen: UIEventSource<boolean> |  | ||||||
|             featureSwitchMoreQuests: UIEventSource<boolean> |  | ||||||
|             featurePipeline: FeaturePipeline |  | ||||||
|             locationControl: UIEventSource<Loc> |  | ||||||
|             backgroundLayer: UIEventSource<BaseLayer> |  | ||||||
|             filteredLayers: UIEventSource<FilteredLayer[]> |  | ||||||
|         } & UserRelatedState, |  | ||||||
|         currentTab: UIEventSource<number>, |  | ||||||
|         isShown: UIEventSource<boolean>, |  | ||||||
|         guistate?: { userInfoIsOpened: UIEventSource<boolean> } |  | ||||||
|     ) { |  | ||||||
|         const tabs = FullWelcomePaneWithTabs.ConstructBaseTabs(state, isShown, currentTab, guistate) |  | ||||||
|         const tabsWithAboutMc = [ |  | ||||||
|             ...FullWelcomePaneWithTabs.ConstructBaseTabs(state, isShown, currentTab, guistate), |  | ||||||
|         ] |  | ||||||
| 
 |  | ||||||
|         tabsWithAboutMc.push({ |  | ||||||
|             header: Svg.help, |  | ||||||
|             content: new Combine([ |  | ||||||
|                 Translations.t.general.aboutMapcomplete.Subs({ |  | ||||||
|                     osmcha_link: Utils.OsmChaLinkFor(7), |  | ||||||
|                 }), |  | ||||||
|                 "<br/>Version " + Constants.vNumber, |  | ||||||
|                 Hotkeys.generateDocumentationDynamic(), |  | ||||||
|             ]).SetClass("link-underline"), |  | ||||||
|         }) |  | ||||||
| 
 |  | ||||||
|         tabs.forEach((c) => c.content.SetClass("p-4")) |  | ||||||
|         tabsWithAboutMc.forEach((c) => c.content.SetClass("p-4")) |  | ||||||
| 
 |  | ||||||
|         return new Toggle( |  | ||||||
|             new TabbedComponent(tabsWithAboutMc, currentTab), |  | ||||||
|             new TabbedComponent(tabs, currentTab), |  | ||||||
|             state.osmConnection.userDetails.map( |  | ||||||
|                 (userdetails: UserDetails) => |  | ||||||
|                     userdetails.loggedIn && |  | ||||||
|                     userdetails.csCount >= Constants.userJourney.mapCompleteHelpUnlock |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  | @ -33,9 +33,3 @@ export interface PresetInfo extends PresetConfig { | ||||||
|     layerToAddTo: FilteredLayer |     layerToAddTo: FilteredLayer | ||||||
|     boundsFactor?: 0.25 | number |     boundsFactor?: 0.25 | number | ||||||
| } | } | ||||||
| 
 |  | ||||||
| export default class SimpleAddUI extends Combine { |  | ||||||
|     constructor(state: SpecialVisualizationState) { |  | ||||||
|         super([]) |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
							
								
								
									
										143
									
								
								UI/DefaultGUI.ts
									
										
									
									
									
								
							
							
						
						
									
										143
									
								
								UI/DefaultGUI.ts
									
										
									
									
									
								
							|  | @ -1,33 +1,15 @@ | ||||||
| import FeaturePipelineState from "../Logic/State/FeaturePipelineState" |  | ||||||
| import { Utils } from "../Utils" | 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 Toggle from "./Input/Toggle" | ||||||
| import BaseUIElement from "./BaseUIElement" |  | ||||||
| import LeftControls from "./BigComponents/LeftControls" | import LeftControls from "./BigComponents/LeftControls" | ||||||
| import RightControls from "./BigComponents/RightControls" | import RightControls from "./BigComponents/RightControls" | ||||||
| import CenterMessageBox from "./CenterMessageBox" | import CenterMessageBox from "./CenterMessageBox" | ||||||
| import ScrollableFullScreen from "./Base/ScrollableFullScreen" | import ScrollableFullScreen from "./Base/ScrollableFullScreen" | ||||||
| import Translations from "./i18n/Translations" | import Translations from "./i18n/Translations" | ||||||
| import SimpleAddUI from "./BigComponents/SimpleAddUI" |  | ||||||
| import StrayClickHandler from "../Logic/Actors/StrayClickHandler" |  | ||||||
| import { DefaultGuiState } from "./DefaultGuiState" | import { DefaultGuiState } from "./DefaultGuiState" | ||||||
| import NewNoteUi from "./Popup/NewNoteUi" |  | ||||||
| import Combine from "./Base/Combine" | import Combine from "./Base/Combine" | ||||||
| import FilteredLayer from "../Models/FilteredLayer" |  | ||||||
| import ExtraLinkButton from "./BigComponents/ExtraLinkButton" | import ExtraLinkButton from "./BigComponents/ExtraLinkButton" | ||||||
| import { VariableUiElement } from "./Base/VariableUIElement" |  | ||||||
| import Img from "./Base/Img" |  | ||||||
| import UserInformationPanel from "./BigComponents/UserInformation" |  | ||||||
| import { LoginToggle } from "./Popup/LoginButton" |  | ||||||
| import { FixedUiElement } from "./Base/FixedUiElement" |  | ||||||
| import GeoLocationHandler from "../Logic/Actors/GeoLocationHandler" | import GeoLocationHandler from "../Logic/Actors/GeoLocationHandler" | ||||||
| import Hotkeys from "./Base/Hotkeys" |  | ||||||
| import CopyrightPanel from "./BigComponents/CopyrightPanel" | import CopyrightPanel from "./BigComponents/CopyrightPanel" | ||||||
| import SvelteUIElement from "./Base/SvelteUIElement" |  | ||||||
| import CommunityIndexView from "./BigComponents/CommunityIndexView.svelte" |  | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * The default MapComplete GUI initializer |  * The default MapComplete GUI initializer | ||||||
|  | @ -36,17 +18,14 @@ import CommunityIndexView from "./BigComponents/CommunityIndexView.svelte" | ||||||
|  */ |  */ | ||||||
| export default class DefaultGUI { | export default class DefaultGUI { | ||||||
|     private readonly guiState: DefaultGuiState |     private readonly guiState: DefaultGuiState | ||||||
|     private readonly state: FeaturePipelineState |  | ||||||
|     private readonly geolocationHandler: GeoLocationHandler | undefined |     private readonly geolocationHandler: GeoLocationHandler | undefined | ||||||
| 
 | 
 | ||||||
|     constructor(state: FeaturePipelineState, guiState: DefaultGuiState) { |     constructor(guiState: DefaultGuiState) { | ||||||
|         this.state = state |  | ||||||
|         this.guiState = guiState |         this.guiState = guiState | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public setup() { |     public setup() { | ||||||
|         this.SetupUIElements() |         this.SetupUIElements() | ||||||
|         this.SetupMap() |  | ||||||
| 
 | 
 | ||||||
|         if ( |         if ( | ||||||
|             this.state.layoutToUse.customCss !== undefined && |             this.state.layoutToUse.customCss !== undefined && | ||||||
|  | @ -54,131 +33,24 @@ export default class DefaultGUI { | ||||||
|         ) { |         ) { | ||||||
|             Utils.LoadCustomCss(this.state.layoutToUse.customCss) |             Utils.LoadCustomCss(this.state.layoutToUse.customCss) | ||||||
|         } |         } | ||||||
| 
 |  | ||||||
|         Hotkeys.RegisterHotkey( |  | ||||||
|             { shift: "O" }, |  | ||||||
|             Translations.t.hotkeyDocumentation.selectMapnik, |  | ||||||
|             () => { |  | ||||||
|                 this.state.backgroundLayer.setData(AvailableBaseLayers.osmCarto) |  | ||||||
|             } |  | ||||||
|         ) |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public setupClickDialogOnMap( |  | ||||||
|         filterViewIsOpened: UIEventSource<boolean>, |  | ||||||
|         state: FeaturePipelineState |  | ||||||
|     ) { |  | ||||||
|         const hasPresets = state.layoutToUse.layers.some((layer) => layer.presets.length > 0) |  | ||||||
|         const noteLayer: FilteredLayer = state.filteredLayers.data.filter( |  | ||||||
|             (l) => l.layerDef.id === "note" |  | ||||||
|         )[0] |  | ||||||
|         let addNewNoteDialog: (isShown: UIEventSource<boolean>) => BaseUIElement = undefined |  | ||||||
|         if (noteLayer !== undefined) { |  | ||||||
|             addNewNoteDialog = (isShown) => new NewNoteUi(noteLayer, isShown, state) |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         function setup() { |  | ||||||
|             if (!hasPresets && addNewNoteDialog === undefined) { |  | ||||||
|                 return // nothing to do
 |  | ||||||
|             } |  | ||||||
|             const newPointDialogIsShown = new UIEventSource<boolean>(false) |  | ||||||
|             const addNewPoint = new ScrollableFullScreen( |  | ||||||
|                 () => |  | ||||||
|                     hasPresets |  | ||||||
|                         ? Translations.t.general.add.title |  | ||||||
|                         : Translations.t.notes.createNoteTitle, |  | ||||||
|                 ({ resetScrollSignal }) => { |  | ||||||
|                     let addNew = undefined |  | ||||||
|                     if (hasPresets) { |  | ||||||
|                         addNew = new SimpleAddUI( |  | ||||||
|                             newPointDialogIsShown, |  | ||||||
|                             resetScrollSignal, |  | ||||||
|                             filterViewIsOpened, |  | ||||||
|                             state |  | ||||||
|                         ) |  | ||||||
|                     } |  | ||||||
|                     let addNote = undefined |  | ||||||
|                     if (noteLayer !== undefined) { |  | ||||||
|                         addNote = addNewNoteDialog(newPointDialogIsShown) |  | ||||||
|                     } |  | ||||||
|                     return new Combine([addNew, addNote]).SetClass("flex flex-col font-lg text-lg") |  | ||||||
|                 }, |  | ||||||
|                 "new", |  | ||||||
|                 newPointDialogIsShown |  | ||||||
|             ) |  | ||||||
| 
 |  | ||||||
|             let noteMarker = undefined |  | ||||||
|             if (!hasPresets && addNewNoteDialog !== undefined) { |  | ||||||
|                 noteMarker = new Combine([ |  | ||||||
|                     Svg.note_svg().SetClass("absolute bottom-0").SetStyle("height: 40px"), |  | ||||||
|                     Svg.addSmall_svg() |  | ||||||
|                         .SetClass("absolute w-6 animate-pulse") |  | ||||||
|                         .SetStyle("right: 10px; bottom: -8px;"), |  | ||||||
|                 ]) |  | ||||||
|                     .SetClass("block relative h-full") |  | ||||||
|                     .SetStyle("left: calc( 50% - 15px )") // This is a bit hacky, yes I know!
 |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (noteLayer !== undefined) { |  | ||||||
|             setup() |  | ||||||
|         } else { |  | ||||||
|             state.featureSwitchAddNew.addCallbackAndRunD((addNewAllowed) => { |  | ||||||
|                 if (addNewAllowed) { |  | ||||||
|                     setup() |  | ||||||
|                     return true |  | ||||||
|                 } |  | ||||||
|             }) |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private SetupMap() { |  | ||||||
|         if (Utils.runningFromConsole) { |  | ||||||
|             return |  | ||||||
|         } |  | ||||||
|         const state = this.state |  | ||||||
|         const guiState = this.guiState |  | ||||||
| 
 |  | ||||||
|         this.setupClickDialogOnMap(guiState.filterViewIsOpened, state) |  | ||||||
| 
 |  | ||||||
|         const selectedElement: FilteredLayer = state.filteredLayers.data.filter( |  | ||||||
|             (l) => l.layerDef.id === "selected_element" |  | ||||||
|         )[0] |  | ||||||
|         new ShowDataLayer({ |  | ||||||
|             leafletMap: state.leafletMap, |  | ||||||
|             layerToShow: selectedElement.layerDef, |  | ||||||
|             features: state.selectedElementsLayer, |  | ||||||
|             state, |  | ||||||
|         }) |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private SetupUIElements() { |     private SetupUIElements() { | ||||||
|         const state = this.state |  | ||||||
|         const guiState = this.guiState |         const guiState = this.guiState | ||||||
| 
 | 
 | ||||||
|         const self = this |  | ||||||
| 
 |  | ||||||
|         const extraLink = Toggle.If( |         const extraLink = Toggle.If( | ||||||
|             state.featureSwitchExtraLinkEnabled, |             state.featureSwitchExtraLinkEnabled, | ||||||
|             () => new ExtraLinkButton(state, state.layoutToUse.extraLink) |             () => new ExtraLinkButton(state, state.layoutToUse.extraLink) | ||||||
|         ) |         ) | ||||||
| 
 | 
 | ||||||
|         const welcomeMessageMapControl = Toggle.If(state.featureSwitchWelcomeMessage, () => |  | ||||||
|             self.InitWelcomeMessage() |  | ||||||
|         ) |  | ||||||
| 
 |  | ||||||
|         new ScrollableFullScreen( |         new ScrollableFullScreen( | ||||||
|             () => Translations.t.general.attribution.attributionTitle, |             () => Translations.t.general.attribution.attributionTitle, | ||||||
|             () => new CopyrightPanel(state), |             () => new CopyrightPanel(state), | ||||||
|             "copyright", |             "copyright", | ||||||
|             guiState.copyrightViewIsOpened |             guiState.copyrightViewIsOpened | ||||||
|         ) |         ) | ||||||
|         const copyright = new MapControlButton(Svg.copyright_svg()).onClick(() => | 
 | ||||||
|             guiState.copyrightViewIsOpened.setData(true) |         new Combine([extraLink]).SetClass("flex flex-col").AttachTo("top-left") | ||||||
|         ) |  | ||||||
|         new Combine([welcomeMessageMapControl, copyright, extraLink]) |  | ||||||
|             .SetClass("flex flex-col") |  | ||||||
|             .AttachTo("top-left") |  | ||||||
| 
 | 
 | ||||||
|         new Combine([ |         new Combine([ | ||||||
|             new ExtraLinkButton(state, { |             new ExtraLinkButton(state, { | ||||||
|  | @ -198,13 +70,4 @@ export default class DefaultGUI { | ||||||
|         new CenterMessageBox(state).AttachTo("centermessage") |         new CenterMessageBox(state).AttachTo("centermessage") | ||||||
|         document?.getElementById("centermessage")?.classList?.add("pointer-events-none") |         document?.getElementById("centermessage")?.classList?.add("pointer-events-none") | ||||||
|     } |     } | ||||||
| 
 |  | ||||||
|     private InitWelcomeMessage(): BaseUIElement { |  | ||||||
|         return new FullWelcomePaneWithTabs( |  | ||||||
|             new UIEventSource<boolean>(false), |  | ||||||
|             this.guiState.welcomeMessageOpenedTab, |  | ||||||
|             this.state, |  | ||||||
|             this.guiState |  | ||||||
|         ) |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -9,7 +9,6 @@ import { Store } from "../../Logic/UIEventSource" | ||||||
| 
 | 
 | ||||||
| export default class SingleReview extends Combine { | export default class SingleReview extends Combine { | ||||||
|     constructor(review: Review & { madeByLoggedInUser: Store<boolean> }) { |     constructor(review: Review & { madeByLoggedInUser: Store<boolean> }) { | ||||||
|         const d = review |  | ||||||
|         const date = new Date(review.iat * 1000) |         const date = new Date(review.iat * 1000) | ||||||
|         const reviewAuthor = |         const reviewAuthor = | ||||||
|             review.metadata.nickname ?? |             review.metadata.nickname ?? | ||||||
|  |  | ||||||
|  | @ -28,6 +28,7 @@ | ||||||
|   import UserRelatedState from "../Logic/State/UserRelatedState"; |   import UserRelatedState from "../Logic/State/UserRelatedState"; | ||||||
|   import LoginToggle from "./Base/LoginToggle.svelte"; |   import LoginToggle from "./Base/LoginToggle.svelte"; | ||||||
|   import LoginButton from "./Base/LoginButton.svelte"; |   import LoginButton from "./Base/LoginButton.svelte"; | ||||||
|  |   import CopyrightPanel from "./BigComponents/CopyrightPanel.js"; | ||||||
| 
 | 
 | ||||||
|   export let state: ThemeViewState; |   export let state: ThemeViewState; | ||||||
|   let layout = state.layout; |   let layout = state.layout; | ||||||
|  | @ -149,6 +150,12 @@ | ||||||
|           <RasterLayerPicker {availableLayers} value={mapproperties.rasterLayer}></RasterLayerPicker> |           <RasterLayerPicker {availableLayers} value={mapproperties.rasterLayer}></RasterLayerPicker> | ||||||
|         </If> |         </If> | ||||||
|       </div> |       </div> | ||||||
|  |        | ||||||
|  |       <div slot="title2"> | ||||||
|  |         <Tr t={Translations.t.general.attribution.title}/> | ||||||
|  |       </div> | ||||||
|  |        | ||||||
|  |       <ToSvelte slot="content2" construct={() => new CopyrightPanel(state)}></ToSvelte> | ||||||
|     </TabbedGroup> |     </TabbedGroup> | ||||||
|   </FloatOver> |   </FloatOver> | ||||||
| </If> | </If> | ||||||
|  |  | ||||||
							
								
								
									
										6
									
								
								Utils.ts
									
										
									
									
									
								
							
							
						
						
									
										6
									
								
								Utils.ts
									
										
									
									
									
								
							|  | @ -308,6 +308,12 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be | ||||||
|         return str |         return str | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * Creates a new array with all elements from 'arr' in such a way that every element will be kept only once | ||||||
|  |      * Elements are returned in the same order as they appear in the lists | ||||||
|  |      * @param arr | ||||||
|  |      * @constructor | ||||||
|  |      */ | ||||||
|     public static Dedup(arr: string[]): string[] { |     public static Dedup(arr: string[]): string[] { | ||||||
|         if (arr === undefined) { |         if (arr === undefined) { | ||||||
|             return undefined |             return undefined | ||||||
|  |  | ||||||
|  | @ -40,7 +40,7 @@ | ||||||
|           "then": { |           "then": { | ||||||
|             "special": { |             "special": { | ||||||
|               "type": "link", |               "type": "link", | ||||||
|               "href":  "{_backend}/messages/inbox", |               "href": "{_backend}/messages/inbox", | ||||||
|               "text": { |               "text": { | ||||||
|                 "en": "Open your inbox", |                 "en": "Open your inbox", | ||||||
|                 "nl": "Ga naar je inbox" |                 "nl": "Ga naar je inbox" | ||||||
|  |  | ||||||
|  | @ -146,6 +146,7 @@ | ||||||
|             "openMapillary": "Open Mapillary here", |             "openMapillary": "Open Mapillary here", | ||||||
|             "openOsmcha": "See latest edits made with {theme}", |             "openOsmcha": "See latest edits made with {theme}", | ||||||
|             "themeBy": "Theme maintained by {author}", |             "themeBy": "Theme maintained by {author}", | ||||||
|  |             "title": "Copyright and attribution", | ||||||
|             "translatedBy": "MapComplete has been translated by {contributors} and <a href='https://github.com/pietervdvn/MapComplete/graphs/contributors' target='_blank'>{hiddenCount} more contributors</a>" |             "translatedBy": "MapComplete has been translated by {contributors} and <a href='https://github.com/pietervdvn/MapComplete/graphs/contributors' target='_blank'>{hiddenCount} more contributors</a>" | ||||||
|         }, |         }, | ||||||
|         "back": "Back", |         "back": "Back", | ||||||
|  |  | ||||||
							
								
								
									
										3
									
								
								test.ts
									
										
									
									
									
								
							
							
						
						
									
										3
									
								
								test.ts
									
										
									
									
									
								
							|  | @ -15,8 +15,6 @@ async function main() { | ||||||
|     const state = new ThemeViewState(layout) |     const state = new ThemeViewState(layout) | ||||||
| 
 | 
 | ||||||
|     const main = new SvelteUIElement(ThemeViewGUI, { state }) |     const main = new SvelteUIElement(ThemeViewGUI, { state }) | ||||||
|     state.guistate.menuIsOpened.setData(true) |  | ||||||
|     state.guistate.menuViewTab.setData("settings") |  | ||||||
|     main.AttachTo("maindiv") |     main.AttachTo("maindiv") | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -24,7 +22,6 @@ async function testspecial() { | ||||||
|     const layout = new LayoutConfig(<any>theme, true) // qp.data === "" ?  : new AllKnownLayoutsLazy().get(qp.data)
 |     const layout = new LayoutConfig(<any>theme, true) // qp.data === "" ?  : new AllKnownLayoutsLazy().get(qp.data)
 | ||||||
|     const state = new ThemeViewState(layout) |     const state = new ThemeViewState(layout) | ||||||
| 
 | 
 | ||||||
|     state.guistate.openUsersettings("picture-license") |  | ||||||
|     const all = SpecialVisualizations.specialVisualizations.map((s) => |     const all = SpecialVisualizations.specialVisualizations.map((s) => | ||||||
|         SpecialVisualizations.renderExampleOfSpecial(state, s) |         SpecialVisualizations.renderExampleOfSpecial(state, s) | ||||||
|     ) |     ) | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue