Chore: housekeeping

This commit is contained in:
Pieter Vander Vennet 2024-06-24 13:11:35 +02:00
parent 18e3e6f806
commit a3a7e74f56
94 changed files with 1273 additions and 1080 deletions

View file

@ -174,7 +174,7 @@ export default class DetermineLayout {
layerConfig.pointRendering
.flatMap((pr) => pr.marker)
.map((iconSpec) => {
if(!iconSpec){
if (!iconSpec) {
return undefined
}
const icon = new TagRenderingConfig(<TagRenderingConfigJson>iconSpec.icon)
@ -192,7 +192,7 @@ export default class DetermineLayout {
})
).join(";")
if(!icon){
if (!icon) {
icon = "./assets/svg/bug.svg"
}

View file

@ -72,7 +72,7 @@ export class LastClickFeatureSource implements FeatureSource {
first_preset: this.renderings[0],
mouse_button: mode ?? "none",
_usermode: this._usermode?.data,
_addNewEnabled: (this._enabledAddMorePoints?.data ?? true) ? "yes" : "no"
_addNewEnabled: this._enabledAddMorePoints?.data ?? true ? "yes" : "no",
}
this.i++

View file

@ -118,7 +118,7 @@ export default class MetaTagging {
}
const state = this.state
const layer = state.layout.getMatchingLayer(feature.properties)
if(!layer){
if (!layer) {
return
}
// Force update if the tags of the element changed

View file

@ -55,7 +55,7 @@ export class Changes {
featureSwitches?: FeatureSwitchState
},
leftRightSensitive: boolean = false,
reportError?: (string: string | Error) => void,
reportError?: (string: string | Error) => void
) {
this._leftRightSensitive = leftRightSensitive
// We keep track of all changes just as well
@ -70,7 +70,7 @@ export class Changes {
state.osmConnection,
state.featurePropertiesStore,
this,
e => this._reportError(e)
(e) => this._reportError(e)
)
this.historicalUserLocations = state.historicalUserLocations
@ -523,9 +523,13 @@ export class Changes {
const osmObj = await downloader.DownloadObjectAsync(id, 0)
return { id, osmObj }
} catch (e) {
this._reportError( "Could not download OSM-object"+
id+
" dropping it from the changes (" + e + ")")
this._reportError(
"Could not download OSM-object" +
id +
" dropping it from the changes (" +
e +
")"
)
console.error(
"Could not download OSM-object",
id,

View file

@ -26,7 +26,7 @@ export class ChangesetHandler {
* @private
*/
private readonly _remappings = new Map<string, string>()
private readonly _reportError: (e: (string | Error)) => void
private readonly _reportError: (e: string | Error) => void
constructor(
dryRun: Store<boolean>,
@ -151,10 +151,10 @@ export class ChangesetHandler {
await this.UpdateTags(csId, extraMetaTags)
}
} catch (e) {
if(this._reportError){
if (this._reportError) {
this._reportError(e)
}
console.warn("Could not open/upload changeset due to ", e,"trying t")
console.warn("Could not open/upload changeset due to ", e, "trying t")
openChangeset.setData(undefined)
throw e
@ -186,7 +186,7 @@ export class ChangesetHandler {
)
await this.UpdateTags(csId, rewrittenTags)
} catch (e) {
if(this._reportError){
if (this._reportError) {
this._reportError(e)
}
console.warn("Could not upload, changeset is probably closed: ", e)

View file

@ -18,14 +18,14 @@ class FeatureSwitchUtils {
key,
"" + defaultValue,
documentation,
{ stackOffset: -1 },
{ stackOffset: -1 }
)
// It takes the current layout, extracts the default value for this query parameter. A query parameter event source is then retrieved and flattened
return queryParam.sync(
(str) => (str === undefined ? defaultValue : str !== "false"),
[],
(b) => (b == defaultValue ? undefined : "" + b),
(b) => (b == defaultValue ? undefined : "" + b)
)
}
}
@ -37,7 +37,7 @@ export class OsmConnectionFeatureSwitches {
this.featureSwitchFakeUser = QueryParameters.GetBooleanQueryParameter(
"fake-user",
false,
"If true, 'dryrun' mode is activated and a fake user account is loaded",
"If true, 'dryrun' mode is activated and a fake user account is loaded"
)
}
}
@ -73,11 +73,9 @@ export default class FeatureSwitchState extends OsmConnectionFeatureSwitches {
super()
this.layoutToUse = layoutToUse
const legacyRewrite: Record<string, string | string[]> = {
"fs-userbadge": "fs-enable-login",
"fs-layers": ["fs-filter", "fs-background"],
}
for (const key in legacyRewrite) {
@ -100,14 +98,14 @@ export default class FeatureSwitchState extends OsmConnectionFeatureSwitches {
this.featureSwitchEnableLogin = FeatureSwitchUtils.initSwitch(
"fs-enable-login",
layoutToUse?.enableUserBadge ?? true,
"Disables/Enables logging in and thus disables editing all together. This effectively puts MapComplete into read-only mode.",
"Disables/Enables logging in and thus disables editing all together. This effectively puts MapComplete into read-only mode."
)
{
if (QueryParameters.wasInitialized("fs-userbadge")) {
// userbadge is the legacy name for 'enable-login'
this.featureSwitchEnableLogin.setData(
QueryParameters.GetBooleanQueryParameter("fs-userbadge", undefined, "Legacy")
.data,
.data
)
}
}
@ -115,60 +113,60 @@ export default class FeatureSwitchState extends OsmConnectionFeatureSwitches {
this.featureSwitchSearch = FeatureSwitchUtils.initSwitch(
"fs-search",
layoutToUse?.enableSearch ?? true,
"Disables/Enables the search bar",
"Disables/Enables the search bar"
)
this.featureSwitchBackgroundSelection = FeatureSwitchUtils.initSwitch(
"fs-background",
layoutToUse?.enableBackgroundLayerSelection ?? true,
"Disables/Enables the background layer control where a user can enable e.g. aerial imagery",
"Disables/Enables the background layer control where a user can enable e.g. aerial imagery"
)
this.featureSwitchFilter = FeatureSwitchUtils.initSwitch(
"fs-filter",
layoutToUse?.enableLayers ?? true,
"Disables/Enables the filter view where a user can enable/disable MapComplete-layers or filter for certain properties",
"Disables/Enables the filter view where a user can enable/disable MapComplete-layers or filter for certain properties"
)
this.featureSwitchWelcomeMessage = FeatureSwitchUtils.initSwitch(
"fs-welcome-message",
true,
"Disables/enables the help menu or welcome message",
"Disables/enables the help menu or welcome message"
)
this.featureSwitchCommunityIndex = FeatureSwitchUtils.initSwitch(
"fs-community-index",
this.featureSwitchEnableLogin.data,
"Disables/enables the button to get in touch with the community",
"Disables/enables the button to get in touch with the community"
)
this.featureSwitchExtraLinkEnabled = FeatureSwitchUtils.initSwitch(
"fs-iframe-popout",
true,
"Disables/Enables the extraLink button. By default, if in iframe mode and the welcome message is hidden, a popout button to the full mapcomplete instance is shown instead (unless disabled with this switch or another extraLink button is enabled)",
"Disables/Enables the extraLink button. By default, if in iframe mode and the welcome message is hidden, a popout button to the full mapcomplete instance is shown instead (unless disabled with this switch or another extraLink button is enabled)"
)
this.featureSwitchBackToThemeOverview = FeatureSwitchUtils.initSwitch(
"fs-homepage-link",
layoutToUse?.enableMoreQuests ?? true,
"Disables/Enables the various links which go back to the index page with the theme overview",
"Disables/Enables the various links which go back to the index page with the theme overview"
)
this.featureSwitchShareScreen = FeatureSwitchUtils.initSwitch(
"fs-share-screen",
layoutToUse?.enableShareScreen ?? true,
"Disables/Enables the 'Share-screen'-tab in the welcome message",
"Disables/Enables the 'Share-screen'-tab in the welcome message"
)
this.featureSwitchGeolocation = FeatureSwitchUtils.initSwitch(
"fs-geolocation",
layoutToUse?.enableGeolocation ?? true,
"Disables/Enables the geolocation button",
"Disables/Enables the geolocation button"
)
this.featureSwitchShowAllQuestions = FeatureSwitchUtils.initSwitch(
"fs-all-questions",
layoutToUse?.enableShowAllQuestions ?? false,
"Always show all questions",
"Always show all questions"
)
this.featureSwitchEnableExport = FeatureSwitchUtils.initSwitch(
"fs-export",
layoutToUse?.enableExportButton ?? true,
"Enable the export as GeoJSON and CSV button",
"Enable the export as GeoJSON and CSV button"
)
let testingDefaultValue = false
@ -182,59 +180,59 @@ export default class FeatureSwitchState extends OsmConnectionFeatureSwitches {
this.featureSwitchIsTesting = QueryParameters.GetBooleanQueryParameter(
"test",
testingDefaultValue,
"If true, 'dryrun' mode is activated. The app will behave as normal, except that changes to OSM will be printed onto the console instead of actually uploaded to osm.org",
"If true, 'dryrun' mode is activated. The app will behave as normal, except that changes to OSM will be printed onto the console instead of actually uploaded to osm.org"
)
this.featureSwitchIsDebugging = QueryParameters.GetBooleanQueryParameter(
"debug",
false,
"If true, shows some extra debugging help such as all the available tags on every object",
"If true, shows some extra debugging help such as all the available tags on every object"
)
this.featureSwitchMorePrivacy = QueryParameters.GetBooleanQueryParameter(
"moreprivacy",
layoutToUse.enableMorePrivacy,
"If true, the location distance indication will not be written to the changeset and other privacy enhancing measures might be taken.",
"If true, the location distance indication will not be written to the changeset and other privacy enhancing measures might be taken."
)
this.overpassUrl = QueryParameters.GetQueryParameter(
"overpassUrl",
(layoutToUse?.overpassUrl ?? Constants.defaultOverpassUrls).join(","),
"Point mapcomplete to a different overpass-instance. Example: https://overpass-api.de/api/interpreter",
"Point mapcomplete to a different overpass-instance. Example: https://overpass-api.de/api/interpreter"
).sync(
(param) => param?.split(","),
[],
(urls) => urls?.join(","),
(urls) => urls?.join(",")
)
this.overpassTimeout = UIEventSource.asInt(
QueryParameters.GetQueryParameter(
"overpassTimeout",
"" + layoutToUse?.overpassTimeout,
"Set a different timeout (in seconds) for queries in overpass",
),
"Set a different timeout (in seconds) for queries in overpass"
)
)
this.overpassMaxZoom = UIEventSource.asFloat(
QueryParameters.GetQueryParameter(
"overpassMaxZoom",
"" + layoutToUse?.overpassMaxZoom,
" point to switch between OSM-api and overpass",
),
" point to switch between OSM-api and overpass"
)
)
this.osmApiTileSize = UIEventSource.asInt(
QueryParameters.GetQueryParameter(
"osmApiTileSize",
"" + layoutToUse?.osmApiTileSize,
"Tilesize when the OSM-API is used to fetch data within a BBOX",
),
"Tilesize when the OSM-API is used to fetch data within a BBOX"
)
)
this.backgroundLayerId = QueryParameters.GetQueryParameter(
"background",
layoutToUse?.defaultBackgroundId,
"The id of the background layer to start with",
"The id of the background layer to start with"
)
}
}

View file

@ -62,7 +62,9 @@ export default class UserRelatedState {
"gps_location_retention"
)
public readonly addNewFeatureMode = new UIEventSource<"button" | "button_click_right" | "button_click" | "click" | "click_right">("button_click_right")
public readonly addNewFeatureMode = new UIEventSource<
"button" | "button_click_right" | "button_click" | "click" | "click_right"
>("button_click_right")
/**
* Preferences as tags exposes many preferences and state properties as record.
@ -134,7 +136,7 @@ export default class UserRelatedState {
"preferences-add-new-mode",
"button_click_right",
{
documentation: "How adding a new feature is done"
documentation: "How adding a new feature is done",
}
)
@ -297,7 +299,7 @@ export default class UserRelatedState {
_applicationOpened: new Date().toISOString(),
_supports_sharing:
typeof window === "undefined" ? "no" : window.navigator.share ? "yes" : "no",
_iframe: Utils.isIframe ? "yes" : "no"
_iframe: Utils.isIframe ? "yes" : "no",
})
for (const key in Constants.userJourney) {

View file

@ -1,14 +1,42 @@
import { Utils } from "../../Utils"
/** This code is autogenerated - do not edit. Edit ./assets/layers/usersettings/usersettings.json instead */
export class ThemeMetaTagging {
public static readonly themeName = "usersettings"
public static readonly themeName = "usersettings"
public metaTaggging_for_usersettings(feat: {properties: Record<string, string>}) {
Utils.AddLazyProperty(feat.properties, '_mastodon_candidate_md', () => feat.properties._description.match(/\[[^\]]*\]\((.*(mastodon|en.osm.town).*)\).*/)?.at(1) )
Utils.AddLazyProperty(feat.properties, '_d', () => feat.properties._description?.replace(/&lt;/g,'<')?.replace(/&gt;/g,'>') ?? '' )
Utils.AddLazyProperty(feat.properties, '_mastodon_candidate_a', () => (feat => {const e = document.createElement('div');e.innerHTML = feat.properties._d;return Array.from(e.getElementsByTagName("a")).filter(a => a.href.match(/mastodon|en.osm.town/) !== null)[0]?.href }) (feat) )
Utils.AddLazyProperty(feat.properties, '_mastodon_link', () => (feat => {const e = document.createElement('div');e.innerHTML = feat.properties._d;return Array.from(e.getElementsByTagName("a")).filter(a => a.getAttribute("rel")?.indexOf('me') >= 0)[0]?.href})(feat) )
Utils.AddLazyProperty(feat.properties, '_mastodon_candidate', () => feat.properties._mastodon_candidate_md ?? feat.properties._mastodon_candidate_a )
feat.properties['__current_backgroun'] = 'initial_value'
}
}
public metaTaggging_for_usersettings(feat: { properties: Record<string, string> }) {
Utils.AddLazyProperty(feat.properties, "_mastodon_candidate_md", () =>
feat.properties._description
.match(/\[[^\]]*\]\((.*(mastodon|en.osm.town).*)\).*/)
?.at(1)
)
Utils.AddLazyProperty(
feat.properties,
"_d",
() => feat.properties._description?.replace(/&lt;/g, "<")?.replace(/&gt;/g, ">") ?? ""
)
Utils.AddLazyProperty(feat.properties, "_mastodon_candidate_a", () =>
((feat) => {
const e = document.createElement("div")
e.innerHTML = feat.properties._d
return Array.from(e.getElementsByTagName("a")).filter(
(a) => a.href.match(/mastodon|en.osm.town/) !== null
)[0]?.href
})(feat)
)
Utils.AddLazyProperty(feat.properties, "_mastodon_link", () =>
((feat) => {
const e = document.createElement("div")
e.innerHTML = feat.properties._d
return Array.from(e.getElementsByTagName("a")).filter(
(a) => a.getAttribute("rel")?.indexOf("me") >= 0
)[0]?.href
})(feat)
)
Utils.AddLazyProperty(
feat.properties,
"_mastodon_candidate",
() => feat.properties._mastodon_candidate_md ?? feat.properties._mastodon_candidate_a
)
feat.properties["__current_backgroun"] = "initial_value"
}
}

View file

@ -2,7 +2,11 @@ import LayoutConfig from "./ThemeConfig/LayoutConfig"
import { SpecialVisualizationState } from "../UI/SpecialVisualization"
import { Changes } from "../Logic/Osm/Changes"
import { Store, UIEventSource } from "../Logic/UIEventSource"
import { FeatureSource, IndexedFeatureSource, WritableFeatureSource } from "../Logic/FeatureSource/FeatureSource"
import {
FeatureSource,
IndexedFeatureSource,
WritableFeatureSource,
} from "../Logic/FeatureSource/FeatureSource"
import { OsmConnection } from "../Logic/Osm/OsmConnection"
import { ExportableMap, MapProperties } from "./MapProperties"
import LayerState from "../Logic/State/LayerState"
@ -46,7 +50,9 @@ import BackgroundLayerResetter from "../Logic/Actors/BackgroundLayerResetter"
import SaveFeatureSourceToLocalStorage from "../Logic/FeatureSource/Actors/SaveFeatureSourceToLocalStorage"
import BBoxFeatureSource from "../Logic/FeatureSource/Sources/TouchesBboxFeatureSource"
import ThemeViewStateHashActor from "../Logic/Web/ThemeViewStateHashActor"
import NoElementsInViewDetector, { FeatureViewState } from "../Logic/Actors/NoElementsInViewDetector"
import NoElementsInViewDetector, {
FeatureViewState,
} from "../Logic/Actors/NoElementsInViewDetector"
import FilteredLayer from "./FilteredLayer"
import { PreferredRasterLayerSelector } from "../Logic/Actors/PreferredRasterLayerSelector"
import { ImageUploadManager } from "../Logic/ImageProviders/ImageUploadManager"
@ -152,7 +158,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
this.featureSwitches = new FeatureSwitchState(layout)
this.guistate = new MenuState(
this.featureSwitches.featureSwitchWelcomeMessage.data,
layout.id,
layout.id
)
this.map = new UIEventSource<MlMap>(undefined)
const geolocationState = new GeoLocationState()
@ -168,14 +174,14 @@ export default class ThemeViewState implements SpecialVisualizationState {
oauth_token: QueryParameters.GetQueryParameter(
"oauth_token",
undefined,
"Used to complete the login",
"Used to complete the login"
),
})
this.userRelatedState = new UserRelatedState(
this.osmConnection,
layout,
this.featureSwitches,
this.mapProperties,
this.mapProperties
)
this.userRelatedState.fixateNorth.addCallbackAndRunD((fixated) => {
this.mapProperties.allowRotating.setData(fixated !== "yes")
@ -186,13 +192,13 @@ export default class ThemeViewState implements SpecialVisualizationState {
geolocationState,
this.selectedElement,
this.mapProperties,
this.userRelatedState.gpsLocationHistoryRetentionTime,
this.userRelatedState.gpsLocationHistoryRetentionTime
)
this.geolocationControl = new GeolocationControlState(this.geolocation, this.mapProperties)
this.availableLayers = AvailableRasterLayers.layersAvailableAt(
this.mapProperties.location,
this.osmConnection.isLoggedIn,
this.osmConnection.isLoggedIn
)
const self = this
@ -204,7 +210,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
const isDisplayed = QueryParameters.GetBooleanQueryParameter(
"overlay-" + rasterInfo.id,
rasterInfo.defaultState ?? true,
"Wether or not overlayer layer " + rasterInfo.id + " is shown",
"Wether or not overlayer layer " + rasterInfo.id + " is shown"
)
const state = { isDisplayed }
overlayLayerStates.set(rasterInfo.id, state)
@ -229,7 +235,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
this.osmConnection.Backend(),
(id) => self.layerState.filteredLayers.get(id).isDisplayed,
mvtAvailableLayers,
this.fullNodeDatabase,
this.fullNodeDatabase
)
let currentViewIndex = 0
@ -247,7 +253,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
id: "current_view_" + currentViewIndex,
}),
]
}),
})
)
this.featuresInView = new BBoxFeatureSource(layoutSource, this.mapProperties.bounds)
@ -265,19 +271,19 @@ export default class ThemeViewState implements SpecialVisualizationState {
featureSwitches: this.featureSwitches,
},
layout?.isLeftRightSensitive() ?? false,
e => this.reportError(e),
(e) => this.reportError(e)
)
this.historicalUserLocations = this.geolocation.historicalUserLocations
this.newFeatures = new NewGeometryFromChangesFeatureSource(
this.changes,
layoutSource,
this.featureProperties,
this.featureProperties
)
layoutSource.addSource(this.newFeatures)
const perLayer = new PerLayerFeatureSourceSplitter(
Array.from(this.layerState.filteredLayers.values()).filter(
(l) => l.layerDef?.source !== null,
(l) => l.layerDef?.source !== null
),
new ChangeGeometryApplicator(this.indexedFeatures, this.changes),
{
@ -288,10 +294,10 @@ export default class ThemeViewState implements SpecialVisualizationState {
"Got ",
features.length,
"leftover features, such as",
features[0].properties,
features[0].properties
)
},
},
}
)
this.perLayer = perLayer.perLayer
}
@ -336,7 +342,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
this.osmObjectDownloader = new OsmObjectDownloader(
this.osmConnection.Backend(),
this.changes,
this.changes
)
this.perLayerFiltered = this.showNormalDataOn(this.map)
@ -347,7 +353,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
currentZoom: this.mapProperties.zoom,
layerState: this.layerState,
bounds: this.visualFeedbackViewportBounds,
},
}
)
this.hasDataInView = new NoElementsInViewDetector(this).hasFeatureInView
this.imageUploadManager = new ImageUploadManager(
@ -355,7 +361,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
Imgur.singleton,
this.featureProperties,
this.osmConnection,
this.changes,
this.changes
)
this.favourites = new FavouritesFeatureSource(this)
@ -398,7 +404,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
LayoutSource.fromCacheZoomLevel,
fs,
this.featureProperties,
fs.layer.layerDef.maxAgeOfCache,
fs.layer.layerDef.maxAgeOfCache
)
toLocalStorage.set(layerId, storage)
})
@ -411,7 +417,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
const doShowLayer = this.mapProperties.zoom.map(
(z) =>
(fs.layer.isDisplayed?.data ?? true) && z >= (fs.layer.layerDef?.minzoom ?? 0),
[fs.layer.isDisplayed],
[fs.layer.isDisplayed]
)
if (!doShowLayer.data && this.featureSwitches.featureSwitchFilter.data === false) {
@ -428,7 +434,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
fs.layer,
fs,
(id) => this.featureProperties.getStore(id),
this.layerState.globalFilters,
this.layerState.globalFilters
)
filteringFeatureSource.set(layerName, filtered)
@ -569,7 +575,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
return
}
this.selectClosestAtCenter(0)
},
}
)
for (let i = 1; i < 9; i++) {
@ -587,7 +593,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
onUp: true,
},
doc,
() => this.selectClosestAtCenter(i - 1),
() => this.selectClosestAtCenter(i - 1)
)
}
@ -604,7 +610,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
if (this.featureSwitches.featureSwitchBackgroundSelection.data) {
this.guistate.backgroundLayerSelectionIsOpened.setData(true)
}
},
}
)
Hotkeys.RegisterHotkey(
{
@ -616,14 +622,14 @@ export default class ThemeViewState implements SpecialVisualizationState {
if (this.featureSwitches.featureSwitchFilter.data) {
this.guistate.openFilterView()
}
},
}
)
Hotkeys.RegisterHotkey(
{ shift: "O" },
Translations.t.hotkeyDocumentation.selectMapnik,
() => {
this.mapProperties.rasterLayer.setData(AvailableRasterLayers.osmCarto)
},
}
)
const setLayerCategory = (category: EliCategory) => {
const available = this.availableLayers.data
@ -631,7 +637,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
const best = RasterLayerUtils.SelectBestLayerAccordingTo(
available,
category,
current.data,
current.data
)
console.log("Best layer for category", category, "is", best.properties.id)
current.setData(best)
@ -640,26 +646,26 @@ export default class ThemeViewState implements SpecialVisualizationState {
Hotkeys.RegisterHotkey(
{ nomod: "O" },
Translations.t.hotkeyDocumentation.selectOsmbasedmap,
() => setLayerCategory("osmbasedmap"),
() => setLayerCategory("osmbasedmap")
)
Hotkeys.RegisterHotkey(
{ nomod: "M" },
Translations.t.hotkeyDocumentation.selectMap,
() => setLayerCategory("map"),
() => setLayerCategory("map")
)
Hotkeys.RegisterHotkey(
{ nomod: "P" },
Translations.t.hotkeyDocumentation.selectAerial,
() => setLayerCategory("photo"),
() => setLayerCategory("photo")
)
Hotkeys.RegisterHotkey(
{ nomod: "L" },
Translations.t.hotkeyDocumentation.geolocate,
() => {
this.geolocationControl.handleClick()
},
}
)
return true
})
@ -671,7 +677,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
Translations.t.hotkeyDocumentation.translationMode,
() => {
Locale.showLinkToWeblate.setData(!Locale.showLinkToWeblate.data)
},
}
)
}
@ -682,7 +688,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
const normalLayers = this.layout.layers.filter(
(l) =>
Constants.priviliged_layers.indexOf(<any>l.id) < 0 &&
!l.id.startsWith("note_import"),
!l.id.startsWith("note_import")
)
const maxzoom = Math.min(...normalLayers.map((l) => l.minzoom))
@ -690,7 +696,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
(l) =>
Constants.priviliged_layers.indexOf(<any>l.id) < 0 &&
l.source.geojsonSource === undefined &&
l.doCount,
l.doCount
)
const summaryTileSource = new SummaryTileSource(
Constants.SummaryServer,
@ -699,7 +705,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
this.mapProperties,
{
isActive: this.mapProperties.zoom.map((z) => z <= maxzoom),
},
}
)
return new SummaryTileSourceRewriter(summaryTileSource, this.layerState.filteredLayers)
}
@ -719,12 +725,12 @@ export default class ThemeViewState implements SpecialVisualizationState {
gps_location_history: this.geolocation.historicalUserLocations,
gps_track: this.geolocation.historicalUserLocationsTrack,
selected_element: new StaticFeatureSource(
this.selectedElement.map((f) => (f === undefined ? empty : [f])),
this.selectedElement.map((f) => (f === undefined ? empty : [f]))
),
range: new StaticFeatureSource(
this.mapProperties.maxbounds.map((bbox) =>
bbox === undefined ? empty : <Feature[]>[bbox.asGeoJson({ id: "range" })],
),
bbox === undefined ? empty : <Feature[]>[bbox.asGeoJson({ id: "range" })]
)
),
current_view: this.currentView,
favourite: this.favourites,
@ -739,7 +745,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
ShowDataLayer.showRange(
this.map,
new StaticFeatureSource([bbox.asGeoJson({ id: "range" })]),
this.featureSwitches.featureSwitchIsTesting,
this.featureSwitches.featureSwitchIsTesting
)
}
const currentViewLayer = this.layout.layers.find((l) => l.id === "current_view")
@ -753,7 +759,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
currentViewLayer,
this.layout,
this.osmObjectDownloader,
this.featureProperties,
this.featureProperties
)
})
}
@ -797,20 +803,20 @@ export default class ThemeViewState implements SpecialVisualizationState {
const lastClickLayerConfig = new LayerConfig(
<LayerConfigJson>last_click_layerconfig,
"last_click",
"last_click"
)
const lastClickFiltered =
lastClickLayerConfig.isShown === undefined
? specialLayers.last_click
: specialLayers.last_click.features.mapD((fs) =>
fs.filter((f) => {
const matches = lastClickLayerConfig.isShown.matchesProperties(
f.properties,
)
console.log("LastClick ", f, "matches", matches)
return matches
}),
)
fs.filter((f) => {
const matches = lastClickLayerConfig.isShown.matchesProperties(
f.properties
)
console.log("LastClick ", f, "matches", matches)
return matches
})
)
new ShowDataLayer(this.map, {
features: new StaticFeatureSource(lastClickFiltered),
layer: lastClickLayerConfig,
@ -855,7 +861,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
this.mapProperties.rasterLayer,
this.availableLayers,
this.featureSwitches.backgroundLayerId,
this.userRelatedState.preferredBackgroundLayer,
this.userRelatedState.preferredBackgroundLayer
)
}
@ -865,14 +871,14 @@ export default class ThemeViewState implements SpecialVisualizationState {
}
public async reportError(message: string | Error) {
console.log(">>> Reporting error to",Constants.ErrorReportServer, message)
console.log(">>> Reporting error to", Constants.ErrorReportServer, message)
let stacktrace: string = new Error().stack
await fetch(Constants.ErrorReportServer, {
method: "POST",
body: JSON.stringify({
stacktrace,
message: ""+message,
message: "" + message,
layout: this.layout.id,
version: Constants.vNumber,
language: this.userRelatedState.language.data,

View file

@ -149,14 +149,13 @@
</LoginToggle>
<a
class="flex button"
class="button flex"
href={window.location.protocol + "//" + window.location.host + "/studio.html"}
>
<Pencil class="mr-2 h-6 w-6" />
<Tr t={Translations.t.general.morescreen.createYourOwnTheme} />
</a>
<h3 id="about">
<Tr t={Translations.t.index.about} />
</h3>
@ -173,8 +172,8 @@
</a>
<a class="flex" href={Utils.OsmChaLinkFor(7)} target="_blank">
<ArrowTrendingUp class="mr-2 h-6 w-6"/>
<Tr t={Translations.t.general.attribution.openOsmchaLastWeek}/>
<ArrowTrendingUp class="mr-2 h-6 w-6" />
<Tr t={Translations.t.general.attribution.openOsmchaLastWeek} />
</a>
<a class="flex" href="https://en.osm.town/@MapComplete" target="_blank">

View file

@ -41,14 +41,14 @@
</slot>
{:else if !silentFail && $loadingStatus === "error"}
<slot name="error">
<div class="alert flex items-center flex-col">
<div class="max-w-64 flex items-center ">
<Invalid class="m-2 h-8 w-8 shrink-0" />
<Tr t={offlineModes[$apiState] ?? t.loginFailedUnreachableMode} />
</div>
<div class="alert flex flex-col items-center">
<div class="max-w-64 flex items-center">
<Invalid class="m-2 h-8 w-8 shrink-0" />
<Tr t={offlineModes[$apiState] ?? t.loginFailedUnreachableMode} />
</div>
<button class="h-fit" on:click={() => state.osmConnection.AttemptLogin()}>
<ArrowPath class="w-6 h-6"/>
<Tr t={t.retry}/>
<ArrowPath class="h-6 w-6" />
<Tr t={t.retry} />
</button>
</div>
</slot>

View file

@ -40,9 +40,9 @@ export default class CopyrightPanel extends Combine {
const t = Translations.t.general.attribution
const layoutToUse = state.layout
const iconAttributions: BaseUIElement[] = Utils.Dedup(layoutToUse
.getUsedImages())
.map(CopyrightPanel.IconAttribution)
const iconAttributions: BaseUIElement[] = Utils.Dedup(layoutToUse.getUsedImages()).map(
CopyrightPanel.IconAttribution
)
let maintainer: BaseUIElement = undefined
if (layoutToUse.credits !== undefined && layoutToUse.credits !== "") {

View file

@ -151,10 +151,10 @@
</div>
{#if Utils.isIframe}
<div class="flex justify-end link-underline">
<a href="https://mapcomplete.org" target="_blank">
<Tr t={Translations.t.general.poweredByMapComplete}/>
</a>
<div class="link-underline flex justify-end">
<a href="https://mapcomplete.org" target="_blank">
<Tr t={Translations.t.general.poweredByMapComplete} />
</a>
</div>
{:else}
<If condition={state.featureSwitches.featureSwitchBackToThemeOverview}>

View file

@ -42,7 +42,7 @@
let knownImages = comparisonState.bindD((ct) => ct.knownImages)
let propertyKeysExternal = comparisonState.mapD((ct) => ct.propertyKeysExternal)
let hasDifferencesAtStart = comparisonState.mapD((ct) => ct.hasDifferencesAtStart)
let enableLogin= state.featureSwitches.featureSwitchEnableLogin
let enableLogin = state.featureSwitches.featureSwitchEnableLogin
</script>
{#if !$sourceUrl || !$enableLogin}

View file

@ -29,10 +29,10 @@
</script>
{#if enableLogin.data}
<AccordionSingle>
<span slot="header" class="p-2 text-base">
<Tr t={t.seeNearby} />
</span>
<NearbyImages {tags} {state} {lon} {lat} {feature} {linkable} {layer} />
</AccordionSingle>
{/if}
<AccordionSingle>
<span slot="header" class="p-2 text-base">
<Tr t={t.seeNearby} />
</span>
<NearbyImages {tags} {state} {lon} {lat} {feature} {linkable} {layer} />
</AccordionSingle>
{/if}

View file

@ -58,7 +58,7 @@
<LoginButton clss="small w-full" osmConnection={state.osmConnection} slot="not-logged-in">
<Tr t={Translations.t.image.pleaseLogin} />
</LoginButton>
<div class="flex flex-col my-4">
<div class="my-4 flex flex-col">
<UploadingImageCounter {state} {tags} />
{#each $errors as error}
<Tr t={error} cls="alert" />

View file

@ -934,7 +934,7 @@ export class ToTextualDescription {
ranges: OpeningRange[][]
): Translation | undefined {
const t = Translations.t.general.opening_hours
if(!ranges){
if (!ranges) {
return undefined
}
if (!ranges?.some((r) => r.length > 0)) {

View file

@ -79,7 +79,7 @@ export default class OpeningHoursVisualization extends Toggle {
// The normal case: we have items for the coming days
return OpeningHoursVisualization.ConstructVizTable(oh, ranges, lastMonday)
}
// The special case that range is completely empty
// The special case that range is completely empty
return OpeningHoursVisualization.ShowSpecialCase(oh)
}
@ -303,6 +303,8 @@ export default class OpeningHoursVisualization extends Toggle {
opensAtDate.getHours(),
opensAtDate.getMinutes()
)}`
return Translations.t.general.opening_hours.closed_until.Subs({ date: opensAtDate.toLocaleString() })
return Translations.t.general.opening_hours.closed_until.Subs({
date: opensAtDate.toLocaleString(),
})
}
}

View file

@ -64,7 +64,9 @@ export class CloseNoteButton implements SpecialVisualization {
zoomButton: string
} = <any>Utils.ParseVisArgs(this.args, args)
let icon: BaseUIElement = new SvelteUIElement(Icon, {icon: params.icon ?? "checkmark.svg"})
let icon: BaseUIElement = new SvelteUIElement(Icon, {
icon: params.icon ?? "checkmark.svg",
})
let textToShow = t.closeNote
if ((params.text ?? "") !== "") {
textToShow = Translations.T(args[0])

View file

@ -110,7 +110,10 @@
</SubtleButton>
</div>
{:else}
<form class="low-interaction rounded-sm p-2 flex flex-col" on:submit|preventDefault={uploadNote}>
<form
class="low-interaction flex flex-col rounded-sm p-2"
on:submit|preventDefault={uploadNote}
>
<label class="neutral-label">
<Tr t={Translations.t.notes.createNoteIntro} />
<div class="w-full p-1">

View file

@ -49,7 +49,7 @@ export default class NoteCommentElement extends Combine {
}
const userinfo = Stores.FromPromise(
Utils.downloadJsonCached<{user: { img: { href: string } }}>(
Utils.downloadJsonCached<{ user: { img: { href: string } } }>(
"https://api.openstreetmap.org/api/0.6/user/" + comment.uid,
24 * 60 * 60 * 1000
)
@ -122,7 +122,7 @@ export default class NoteCommentElement extends Combine {
public static addCommentTo(
txt: string,
tags: UIEventSource<any>,
state: { osmConnection: {userDetails: Store<{ name: string, uid: number }>} }
state: { osmConnection: { userDetails: Store<{ name: string; uid: number }> } }
) {
const comments: any[] = JSON.parse(tags.data["comments"])
const username = state.osmConnection.userDetails.data.name

View file

@ -111,93 +111,97 @@
</script>
{#if $loginEnabled}
<div
bind:this={questionboxElem}
aria-live="polite"
class="marker-questionbox-root"
class:hidden={$questionsToAsk.length === 0 && skipped === 0 && answered === 0}
>
{#if $allQuestionsToAsk.length === 0}
{#if skipped + answered > 0}
<div class="thanks">
<Tr t={Translations.t.general.questionBox.done} />
</div>
{#if answered === 0}
{#if skipped === 1}
<Tr t={Translations.t.general.questionBox.skippedOne} />
{:else}
<Tr t={Translations.t.general.questionBox.skippedMultiple.Subs({ skipped })} />
{/if}
{:else if answered === 1}
{#if skipped === 0}
<Tr t={Translations.t.general.questionBox.answeredOne} />
{:else if skipped === 1}
<Tr t={Translations.t.general.questionBox.answeredOneSkippedOne} />
{:else}
<Tr t={Translations.t.general.questionBox.answeredOneSkippedMultiple.Subs({ skipped })} />
{/if}
{:else if skipped === 0}
<Tr t={Translations.t.general.questionBox.answeredMultiple.Subs({ answered })} />
{:else if skipped === 1}
<Tr t={Translations.t.general.questionBox.answeredMultipleSkippedOne.Subs({ answered })} />
{:else}
<Tr
t={Translations.t.general.questionBox.answeredMultipleSkippedMultiple.Subs({
answered,
skipped,
})}
/>
{/if}
{#if skipped > 0}
<button
class="w-full"
on:click={() => {
skippedQuestions.setData(new Set())
skipped = 0
}}
>
<Tr t={Translations.t.general.questionBox.reactivate} />
</button>
{/if}
{/if}
{:else}
<div>
{#if $showAllQuestionsAtOnce}
<div class="flex flex-col gap-y-1">
{#each $allQuestionsToAsk as question (question.id)}
<TagRenderingQuestionDynamic
config={question}
{tags}
{selectedElement}
{state}
{layer}
/>
{/each}
<div
bind:this={questionboxElem}
aria-live="polite"
class="marker-questionbox-root"
class:hidden={$questionsToAsk.length === 0 && skipped === 0 && answered === 0}
>
{#if $allQuestionsToAsk.length === 0}
{#if skipped + answered > 0}
<div class="thanks">
<Tr t={Translations.t.general.questionBox.done} />
</div>
{:else if $firstQuestion !== undefined}
<TagRenderingQuestionDynamic
config={$firstQuestion}
{layer}
{selectedElement}
{state}
{tags}
on:saved={() => {
skip($firstQuestion, true)
}}
>
{#if answered === 0}
{#if skipped === 1}
<Tr t={Translations.t.general.questionBox.skippedOne} />
{:else}
<Tr t={Translations.t.general.questionBox.skippedMultiple.Subs({ skipped })} />
{/if}
{:else if answered === 1}
{#if skipped === 0}
<Tr t={Translations.t.general.questionBox.answeredOne} />
{:else if skipped === 1}
<Tr t={Translations.t.general.questionBox.answeredOneSkippedOne} />
{:else}
<Tr
t={Translations.t.general.questionBox.answeredOneSkippedMultiple.Subs({ skipped })}
/>
{/if}
{:else if skipped === 0}
<Tr t={Translations.t.general.questionBox.answeredMultiple.Subs({ answered })} />
{:else if skipped === 1}
<Tr
t={Translations.t.general.questionBox.answeredMultipleSkippedOne.Subs({ answered })}
/>
{:else}
<Tr
t={Translations.t.general.questionBox.answeredMultipleSkippedMultiple.Subs({
answered,
skipped,
})}
/>
{/if}
{#if skipped > 0}
<button
class="secondary"
class="w-full"
on:click={() => {
skip($firstQuestion)
skippedQuestions.setData(new Set())
skipped = 0
}}
slot="cancel"
>
<Tr t={Translations.t.general.skip} />
<Tr t={Translations.t.general.questionBox.reactivate} />
</button>
</TagRenderingQuestionDynamic>
{/if}
{/if}
</div>
{/if}
</div>
{/if}
{:else}
<div>
{#if $showAllQuestionsAtOnce}
<div class="flex flex-col gap-y-1">
{#each $allQuestionsToAsk as question (question.id)}
<TagRenderingQuestionDynamic
config={question}
{tags}
{selectedElement}
{state}
{layer}
/>
{/each}
</div>
{:else if $firstQuestion !== undefined}
<TagRenderingQuestionDynamic
config={$firstQuestion}
{layer}
{selectedElement}
{state}
{tags}
on:saved={() => {
skip($firstQuestion, true)
}}
>
<button
class="secondary"
on:click={() => {
skip($firstQuestion)
}}
slot="cancel"
>
<Tr t={Translations.t.general.skip} />
</button>
</TagRenderingQuestionDynamic>
{/if}
</div>
{/if}
</div>
{/if}

View file

@ -28,7 +28,7 @@
</script>
{#if config !== undefined && (config?.condition === undefined || config.condition.matchesProperties($tags))}
<div {id} class={twMerge("link-underline flex w-full h-full flex-col", extraClasses)}>
<div {id} class={twMerge("link-underline flex h-full w-full flex-col", extraClasses)}>
{#if $trs.length === 1}
<TagRenderingMapping
mapping={$trs[0]}

View file

@ -106,8 +106,16 @@
</TagRenderingQuestion>
{:else}
<div class="low-interaction flex items-center justify-between overflow-hidden rounded pl-2">
<TagRenderingAnswer id={answerId} {config} {tags} {selectedElement} {state} {layer} extraClasses="my-2"/>
{#if (!editingEnabled || $editingEnabled)}
<TagRenderingAnswer
id={answerId}
{config}
{tags}
{selectedElement}
{state}
{layer}
extraClasses="my-2"
/>
{#if !editingEnabled || $editingEnabled}
<EditButton
arialabel={config.editButtonAriaLabel}
ariaLabelledBy={answerId}

View file

@ -1,5 +1,4 @@
<script lang="ts">
</script>
<main >
</main>
<main />

View file

@ -124,11 +124,11 @@
state.mapProperties.installCustomKeyboardHandler(viewport)
let canZoomIn = mapproperties.maxzoom.map(
(mz) => mapproperties.zoom.data < mz,
[mapproperties.zoom],
[mapproperties.zoom]
)
let canZoomOut = mapproperties.minzoom.map(
(mz) => mapproperties.zoom.data > mz,
[mapproperties.zoom],
[mapproperties.zoom]
)
function updateViewport() {
@ -165,7 +165,7 @@
onDestroy(
rasterLayer.addCallbackAndRunD((l) => {
rasterLayerName = l.properties.name
}),
})
)
let previewedImage = state.previewedImage
@ -196,7 +196,7 @@
let openMapButton: UIEventSource<HTMLElement> = new UIEventSource<HTMLElement>(undefined)
let openMenuButton: UIEventSource<HTMLElement> = new UIEventSource<HTMLElement>(undefined)
let openCurrentViewLayerButton: UIEventSource<HTMLElement> = new UIEventSource<HTMLElement>(
undefined,
undefined
)
let _openNewElementButton: HTMLButtonElement
let openNewElementButton: UIEventSource<HTMLElement> = new UIEventSource<HTMLElement>(undefined)
@ -572,7 +572,6 @@
<div class="link-underline links-w-full m-2 flex flex-col gap-y-1" slot="content0">
<Tr t={Translations.t.general.aboutMapComplete.intro} />
<a class="flex" href={Utils.HomepageLink()}>
<Add class="h-6 w-6" />
{#if Utils.isIframe}

View file

@ -146,7 +146,6 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
public static readonly isIframe = !Utils.runningFromConsole && window !== window.top
public static initDomPurify() {
if (Utils.runningFromConsole) {
return

View file

@ -1,7 +1,7 @@
{
"contributors": [
{
"commits": 7596,
"commits": 7612,
"contributor": "Pieter Vander Vennet"
},
{

View file

@ -5,7 +5,7 @@
"contributor": "Pieter Vander Vennet"
},
{
"commits": 347,
"commits": 351,
"contributor": "kjon"
},
{
@ -21,7 +21,7 @@
"contributor": "Robin van der Linde"
},
{
"commits": 67,
"commits": 69,
"contributor": "mcliquid"
},
{
@ -112,6 +112,10 @@
"commits": 13,
"contributor": "Joost"
},
{
"commits": 12,
"contributor": "Patchanka64"
},
{
"commits": 12,
"contributor": "Ettore Atalan"
@ -152,10 +156,6 @@
"commits": 10,
"contributor": "Irina"
},
{
"commits": 9,
"contributor": "Patchanka64"
},
{
"commits": 9,
"contributor": "Manuel Tassi"
@ -256,6 +256,10 @@
"commits": 6,
"contributor": "lvgx"
},
{
"commits": 5,
"contributor": "Christian Schmidt"
},
{
"commits": 5,
"contributor": "Emory Shaw"