2020-06-24 00:35:19 +02:00
import { OsmConnection } from "./Logic/OsmConnection" ;
import { Changes } from "./Logic/Changes" ;
import { ElementStorage } from "./Logic/ElementStorage" ;
import { UIEventSource } from "./UI/UIEventSource" ;
import { UserBadge } from "./UI/UserBadge" ;
import { Basemap } from "./Logic/Basemap" ;
import { PendingChanges } from "./UI/PendingChanges" ;
import { CenterMessageBox } from "./UI/CenterMessageBox" ;
import { Helpers } from "./Helpers" ;
import { KnownSet } from "./Layers/KnownSet" ;
2020-06-29 03:12:44 +02:00
import { Tag , TagUtils } from "./Logic/TagsFilter" ;
2020-06-24 00:35:19 +02:00
import { FilteredLayer } from "./Logic/FilteredLayer" ;
import { LayerUpdater } from "./Logic/LayerUpdater" ;
2020-06-27 03:06:51 +02:00
import { UIElement } from "./UI/UIElement" ;
import { MessageBoxHandler } from "./UI/MessageBoxHandler" ;
import { Overpass } from "./Logic/Overpass" ;
import { FeatureInfoBox } from "./UI/FeatureInfoBox" ;
2020-06-28 02:42:22 +02:00
import { GeoLocationHandler } from "./Logic/GeoLocationHandler" ;
2020-06-29 03:12:44 +02:00
import { StrayClickHandler } from "./Logic/StrayClickHandler" ;
import { SimpleAddUI } from "./UI/SimpleAddUI" ;
import { VariableUiElement } from "./UI/Base/VariableUIElement" ;
2020-07-01 02:12:33 +02:00
import { SearchAndGo } from "./UI/SearchAndGo" ;
2020-06-24 00:35:19 +02:00
2020-06-25 03:39:31 +02:00
let dryRun = false ;
2020-06-24 00:35:19 +02:00
2020-06-25 03:39:31 +02:00
if ( location . hostname === "localhost" || location . hostname === "127.0.0.1" ) {
// Set to true if testing and changes should NOT be saved
2020-07-01 16:32:17 +02:00
// dryRun = true;
2020-06-25 03:39:31 +02:00
// If you have a testfile somewhere, enable this to spoof overpass
// This should be hosted independantly, e.g. with `cd assets; webfsd -p 8080` + a CORS plugin to disable cors rules
2020-07-01 16:32:17 +02:00
Overpass . testUrl = null ; // "http://127.0.0.1:8080/test.json";
2020-06-25 03:39:31 +02:00
}
2020-06-24 00:35:19 +02:00
// ----------------- SELECT THE RIGHT QUESTSET -----------------
2020-06-27 03:06:51 +02:00
2020-06-24 00:35:19 +02:00
let questSetToRender = KnownSet . groen ;
if ( window . location . search ) {
const params = window . location . search . substr ( 1 ) . split ( "&" ) ;
const paramDict : any = { } ;
for ( const param of params ) {
var kv = param . split ( "=" ) ;
paramDict [ kv [ 0 ] ] = kv [ 1 ] ;
}
if ( paramDict . quests ) {
questSetToRender = KnownSet . allSets [ paramDict . quests ] ;
console . log ( "Using quests: " , questSetToRender . name ) ;
}
}
document . title = questSetToRender . title ;
// ----------------- Setup a few event sources -------------
// The message that should be shown at the center of the screen
const centerMessage = new UIEventSource < string > ( "" ) ;
// The countdown: if set to e.g. ten, it'll start counting down. When reaching zero, changes will be saved. NB: this is implemented later, not in the eventSource
const secondsTillChangesAreSaved = new UIEventSource < number > ( 0 ) ;
2020-06-27 03:06:51 +02:00
const leftMessage = new UIEventSource < ( ) = > UIElement > ( undefined ) ;
const selectedElement = new UIEventSource < any > ( undefined ) ;
2020-07-01 17:38:48 +02:00
const preferedPictureLicense = new UIEventSource < string > ( undefined ) ;
2020-06-27 03:06:51 +02:00
2020-06-29 03:12:44 +02:00
const locationControl = new UIEventSource < { lat : number , lon : number , zoom : number } > ( {
2020-06-24 00:35:19 +02:00
zoom : questSetToRender.startzoom ,
lat : questSetToRender.startLat ,
lon : questSetToRender.startLon
} ) ;
// ----------------- Prepare the important objects -----------------
2020-06-27 03:06:51 +02:00
const saveTimeout = 5000 ; // After this many milliseconds without changes, saves are sent of to OSM
2020-06-24 00:35:19 +02:00
const allElements = new ElementStorage ( ) ;
const osmConnection = new OsmConnection ( dryRun ) ;
2020-06-27 03:06:51 +02:00
const changes = new Changes (
"Beantwoorden van vragen met MapComplete voor vragenset #" + questSetToRender . name ,
osmConnection , allElements , centerMessage ) ;
2020-06-29 03:12:44 +02:00
const bm = new Basemap ( "leafletDiv" , locationControl , new VariableUiElement (
locationControl . map ( ( location ) = > {
const mapComplete = "<a href='https://github.com/pietervdvn/MapComplete' target='_blank'>Mapcomple</a> " +
" " +
"<a href='https://github.com/pietervdvn/MapComplete/issues' target='_blank'><img src='./assets/bug.svg' alt='Report bug' class='small-userbadge-icon'></a>" ;
let editHere = "" ;
if ( location !== undefined ) {
editHere = " | " +
"<a href='https://www.openstreetmap.org/edit?editor=id#map=" + location . zoom + "/" + location . lat + "/" + location . lon + "' target='_blank'>" +
"<img src='./assets/pencil.svg' alt='edit here' class='small-userbadge-icon'>" +
"</a>"
}
return mapComplete + editHere ;
} )
) ) ;
2020-06-24 00:35:19 +02:00
2020-07-01 17:38:48 +02:00
// ------------- Tie together user settings and UI -----------
const picturesPrefName = "mapcomplete-pictures-license" ;
preferedPictureLicense . addCallback ( ( license ) = > {
osmConnection . SetPreference ( picturesPrefName , license ) ;
} ) ;
osmConnection . preferences . addCallback ( ( prefs ) = > {
if ( prefs [ picturesPrefName ] !== undefined ) {
preferedPictureLicense . setData ( prefs [ picturesPrefName ] ) ;
}
} )
2020-06-24 00:35:19 +02:00
// ------------- Setup the layers -------------------------------
const addButtons : {
name : string ,
icon : string ,
tags : Tag [ ] ,
layerToAddTo : FilteredLayer
} [ ]
= [ ] ;
const flayers : FilteredLayer [ ] = [ ]
for ( const layer of questSetToRender . layers ) {
2020-07-01 16:32:17 +02:00
const generateInfo = ( tagsES ) = > {
return new FeatureInfoBox (
tagsES ,
layer . elementsToShow ,
layer . questions ,
changes ,
2020-07-01 17:38:48 +02:00
osmConnection . userDetails ,
preferedPictureLicense
2020-07-01 16:32:17 +02:00
)
} ;
const flayer = layer . asLayer ( bm , allElements , changes , osmConnection . userDetails , selectedElement ,
generateInfo ) ;
2020-06-24 00:35:19 +02:00
const addButton = {
name : layer.name ,
icon : layer.icon ,
tags : layer.newElementTags ,
layerToAddTo : flayer
}
addButtons . push ( addButton ) ;
flayers . push ( flayer ) ;
}
const layerUpdater = new LayerUpdater ( bm , questSetToRender . startzoom , flayers ) ;
// ------------------ Setup various UI elements ------------
2020-06-29 03:12:44 +02:00
new StrayClickHandler ( bm , selectedElement , leftMessage , ( ) = > {
return new SimpleAddUI ( bm . Location ,
bm . LastClickLocation ,
changes ,
selectedElement ,
2020-06-29 03:40:19 +02:00
layerUpdater . runningQuery ,
2020-06-29 16:21:36 +02:00
osmConnection . userDetails ,
2020-06-29 03:12:44 +02:00
addButtons ) ;
}
) ;
2020-06-27 03:06:51 +02:00
/ * *
* Show the questions and information for the selected element on the leftMessage
* /
selectedElement . addCallback ( ( data ) = > {
2020-06-29 03:12:44 +02:00
// Which is the applicable set?
for ( const layer of questSetToRender . layers ) {
const applicable = layer . overpassFilter . matches ( TagUtils . proprtiesToKV ( data ) ) ;
if ( applicable ) {
// This layer is the layer that gives the questions
leftMessage . setData ( ( ) = >
new FeatureInfoBox (
allElements . getElement ( data . id ) ,
layer . elementsToShow ,
layer . questions ,
changes ,
2020-07-01 17:38:48 +02:00
osmConnection . userDetails ,
preferedPictureLicense
2020-06-29 03:12:44 +02:00
) ) ;
break ;
2020-06-27 03:06:51 +02:00
}
2020-06-29 03:12:44 +02:00
}
2020-06-27 03:06:51 +02:00
}
) ;
2020-06-24 00:35:19 +02:00
2020-06-29 03:12:44 +02:00
2020-06-27 03:06:51 +02:00
const pendingChanges = new PendingChanges (
changes . pendingChangesES , secondsTillChangesAreSaved , changes . isSaving ) ;
2020-06-24 00:35:19 +02:00
2020-06-29 03:12:44 +02:00
new UserBadge ( osmConnection . userDetails , pendingChanges , bm )
2020-06-24 00:35:19 +02:00
. AttachTo ( 'userbadge' ) ;
2020-07-01 02:12:33 +02:00
new SearchAndGo ( bm ) . AttachTo ( "searchbox" ) ;
2020-06-27 03:06:51 +02:00
var welcomeMessage = ( ) = > {
return new VariableUiElement (
osmConnection . userDetails . map ( ( userdetails ) = > {
var login = questSetToRender . gettingStartedPlzLogin ;
if ( userdetails . loggedIn ) {
login = questSetToRender . welcomeBackMessage ;
}
return "<div id='welcomeMessage'>" +
questSetToRender . welcomeMessage + login +
"</div>" ;
} ) ,
2020-06-29 03:12:44 +02:00
function ( ) {
2020-06-27 03:06:51 +02:00
osmConnection . registerActivateOsmAUthenticationClass ( )
} ) ;
}
leftMessage . setData ( welcomeMessage ) ;
2020-06-29 16:21:36 +02:00
welcomeMessage ( ) . AttachTo ( "messagesbox" ) ;
2020-06-24 00:35:19 +02:00
2020-06-27 03:06:51 +02:00
var messageBox = new MessageBoxHandler ( leftMessage , ( ) = > { selectedElement . setData ( undefined ) } ) ;
2020-06-24 00:35:19 +02:00
new CenterMessageBox (
questSetToRender . startzoom ,
centerMessage ,
osmConnection ,
locationControl ,
layerUpdater . runningQuery )
. AttachTo ( "centermessage" ) ;
2020-06-27 03:06:51 +02:00
Helpers . SetupAutoSave ( changes , secondsTillChangesAreSaved , saveTimeout ) ;
2020-06-24 00:35:19 +02:00
Helpers . LastEffortSave ( changes ) ;
2020-06-27 03:06:51 +02:00
osmConnection . registerActivateOsmAUthenticationClass ( ) ;
2020-06-24 00:35:19 +02:00
2020-06-28 02:42:22 +02:00
new GeoLocationHandler ( bm ) . AttachTo ( "geolocate-button" ) ;
2020-06-24 00:35:19 +02:00
// --------------- Send a ping to start various action --------
locationControl . ping ( ) ;
2020-06-27 03:06:51 +02:00
messageBox . update ( ) ;