Fixes, surveillance cams v0.1

This commit is contained in:
Pieter Vander Vennet 2020-11-13 23:58:11 +01:00
parent b329bbbdb3
commit ba44024dd9
10 changed files with 137 additions and 65 deletions

View file

@ -15,10 +15,11 @@ import * as benches from "../assets/themes/benches/benches.json";
import * as charging_stations from "../assets/themes/charging_stations/charging_stations.json"
import * as widths from "../assets/themes/widths/width.json"
import * as drinking_water from "../assets/themes/drinking_water/drinking_water.json"
import LayerConfig from "./JSON/LayerConfig";
import SharedLayers from "./SharedLayers";
import * as surveillance_cameras from "../assets/themes/surveillance_cameras/surveillance_cameras.json"
import * as personal from "../assets/themes/personalLayout/personalLayout.json"
import LayerConfig from "./JSON/LayerConfig";
import LayoutConfig from "./JSON/LayoutConfig";
import SharedLayers from "./SharedLayers";
export class AllKnownLayouts {
@ -60,6 +61,7 @@ export class AllKnownLayouts {
new LayoutConfig(widths),
new LayoutConfig(buurtnatuur),
new LayoutConfig(bike_monitoring_stations),
new LayoutConfig(surveillance_cameras)
];

View file

@ -442,7 +442,7 @@ export class InitUiElements {
State.state.layerUpdater = new UpdateFromOverpass(State.state);
State.state.availableBackgroundLayers = new AvailableBaseLayers(State.state).availableEditorLayers;
const queryParam = QueryParameters.GetQueryParameter("background", State.state.layoutToUse.data.defaultBackgroundId);
const queryParam = QueryParameters.GetQueryParameter("background", State.state.layoutToUse.data.defaultBackgroundId, "The id of the background layer to start with");
queryParam.addCallbackAndRun((selectedId: string) => {
const available = State.state.availableBackgroundLayers.data;
@ -483,7 +483,7 @@ export class InitUiElements {
const flayer: FilteredLayer = FilteredLayer.fromDefinition(layer, generateInfo);
flayers.push(flayer);
QueryParameters.GetQueryParameter("layer-" + layer.id, "true")
QueryParameters.GetQueryParameter("layer-" + layer.id, "true", "Wehter or not layer "+layer.id+" is shown")
.map<boolean>((str) => str !== "false", [], (b) => b.toString())
.syncWith(
flayer.isDisplayed

View file

@ -5,20 +5,22 @@ import {UIEventSource} from "../UIEventSource";
export class QueryParameters {
private static order: string [] = ["layout","test","z","lat","lon"];
private static order: string [] = ["layout", "test", "z", "lat", "lon"];
private static knownSources = {};
private static initialized = false;
private static defaults = {}
private static addOrder(key){
if(this.order.indexOf(key) < 0){
private static documentation = {}
private static addOrder(key) {
if (this.order.indexOf(key) < 0) {
this.order.push(key)
}
}
private static init() {
if(this.initialized){
if (this.initialized) {
return;
}
this.initialized = true;
@ -63,6 +65,7 @@ export class QueryParameters {
if(!this.initialized){
this.init();
}
QueryParameters.documentation[key] = documentation;
if (deflt !== undefined) {
QueryParameters.defaults[key] = deflt;
}
@ -76,4 +79,12 @@ export class QueryParameters {
return source;
}
public static GenerateQueryParameterDocs(): string {
const docs = [];
for (const key in QueryParameters.documentation) {
docs.push("**" + key + "**: " + QueryParameters.documentation[key] + " (default value: _" + QueryParameters.defaults[key] + "_)")
}
return docs.join("\n\n");
}
}

View file

@ -103,7 +103,7 @@ A theme has translations into the preset.json (`assets/themes/themename/themenam
1. Modify `"language"` to contain the new language, e.g. `"language": "nl"` becomes `"language": ["nl", "en"]`
2. Add extra strings to the texts. If it used to be a single-language theme, one can replace the strings, e.g.: `"description": "Welcome to Open Bookcase Map"` to `"description": {"en": "Welcome to Open Bookcase Map", "nl": "Welkom bij de OpenBoekenruilkastenKaart", "fr": "Bienvenue sûr la carte des petites bibliotheques"}`. If the correct language is not found, it'll fallback to another supported language.
3. If you notice missing translations in the core of MapComplete, fork this project, open [the file containing all translations](https://github.com/pietervdvn/MapComplete/blob/master/UI/i18n/Translations.ts), add add a language string there
3. If you notice missing translations in the core of MapComplete, fork this project, open [the file containing all translations](https://github.com/pietervdvn/MapComplete/blob/master/assets/translations.json), add add a language string there
4. Send a pull request to update the languages, I'll gladly add it! It doesn't have to be a complete translation from the start ;)
### Adding your theme to the repository
@ -165,6 +165,50 @@ Whenever a change is made -even adding a single tag- the change is uploaded into
Note that changesets are closed automatically after one hour of inactivity, so we don't have to worry about closing them.
### Query parameters
By adding extra query parameters, more options are available to influence:
**test**: 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 (default value: _false_)
**layout**: The layout to load into MapComplete (default value: _bookcases_)
**userlayout**: undefined (default value: _false_)
**layer-control-toggle**: Wether or not the layer control is shown (default value: _false_)
**tab**: The tab that is shown in the welcome-message. 0 = the explanation of the theme,1 = OSM-credits, 2 = sharescreen, 3 = more themes, 4 = about mapcomplete (user must be logged in and have >200 changesets) (default value: _0_)
**z**: The initial/current zoom level (default value: _1_)
**lat**: The initial/current latitude (default value: _0_)
**lon**: The initial/current longitude of the app (default value: _0_)
**fs-userbadge**: Disables/Enables the userbadge (and thus disables login capabilities) (default value: _true_)
**fs-search**: Disables/Enables the search bar (default value: _true_)
**fs-layers**: Disables/Enables the layer control (default value: _true_)
**fs-add-new**: Disables/Enables the 'add new feature'-popup. (A theme without presets might not have it in the first place) (default value: _true_)
**fs-welcome-message**: undefined (default value: _true_)
**fs-iframe**: Disables/Enables the iframe-popup (default value: _false_)
**fs-more-quests**: Disables/Enables the 'More Quests'-tab in the welcome message (default value: _true_)
**fs-share-screen**: Disables/Enables the 'Share-screen'-tab in the welcome message (default value: _true_)
**fs-geolocation**: Disables/Enables the geolocation button (default value: _true_)
**oauth_token**: Used to complete the login (default value: _undefined_)
**background**: The id of the background layer to start with (default value: _undefined_)
**layer-bookcases**: Wehter or not layer bookcases is shown (default value: _true_) index.ts:104:8
# Privacy
Privacy is important, we try to leak as little information as possible.

View file

@ -115,10 +115,10 @@ export default class State {
public layoutDefinition: string;
public installedThemes: UIEventSource<{ layout: LayoutConfig; definition: string }[]>;
public layerControlIsOpened: UIEventSource<boolean> = QueryParameters.GetQueryParameter("layer-control-toggle", "false")
public layerControlIsOpened: UIEventSource<boolean> = QueryParameters.GetQueryParameter("layer-control-toggle", "false", "Wether or not the layer control is shown")
.map<boolean>((str) => str !== "false", [], b => "" + b)
public welcomeMessageOpenedTab = QueryParameters.GetQueryParameter("tab", "0").map<number>(
public welcomeMessageOpenedTab = QueryParameters.GetQueryParameter("tab", "0", `The tab that is shown in the welcome-message. 0 = the explanation of the theme,1 = OSM-credits, 2 = sharescreen, 3 = more themes, 4 = about mapcomplete (user must be logged in and have >${State.userJourney.mapCompleteHelpUnlock} changesets)`).map<number>(
str => isNaN(Number(str)) ? 0 : Number(str), [], n => "" + n
);
@ -138,11 +138,11 @@ export default class State {
})
}
this.zoom = asFloat(
QueryParameters.GetQueryParameter("z", "" + layoutToUse.startZoom)
QueryParameters.GetQueryParameter("z", "" + layoutToUse.startZoom, "The initial/current zoom level")
.syncWith(LocalStorageSource.Get("zoom")));
this.lat = asFloat(QueryParameters.GetQueryParameter("lat", "" + layoutToUse.startLat)
this.lat = asFloat(QueryParameters.GetQueryParameter("lat", "" + layoutToUse.startLat, "The initial/current latitude")
.syncWith(LocalStorageSource.Get("lat")));
this.lon = asFloat(QueryParameters.GetQueryParameter("lon", "" + layoutToUse.startLon)
this.lon = asFloat(QueryParameters.GetQueryParameter("lon", "" + layoutToUse.startLon, "The initial/current longitude of the app")
.syncWith(LocalStorageSource.Get("lon")));
@ -165,8 +165,8 @@ export default class State {
});
function featSw(key: string, deflt: (layout: LayoutConfig) => boolean, documentation?: string): UIEventSource<boolean> {
const queryParameterSource = QueryParameters.GetQueryParameter(key, undefined);
function featSw(key: string, deflt: (layout: LayoutConfig) => boolean, documentation: string): UIEventSource<boolean> {
const queryParameterSource = QueryParameters.GetQueryParameter(key, undefined, documentation);
// I'm so sorry about someone trying to decipher this
// It takes the current layout, extracts the default value for this query paramter. A query parameter event source is then retreived and flattened
@ -180,20 +180,30 @@ export default class State {
this.featureSwitchUserbadge = featSw("fs-userbadge", (layoutToUse) => layoutToUse?.enableUserBadge ?? true,
"Disables the userbadge (and thus disables login capabilities)");
this.featureSwitchSearch = featSw("fs-search", (layoutToUse) => layoutToUse?.enableSearch ?? true);
this.featureSwitchLayers = featSw("fs-layers", (layoutToUse) => layoutToUse?.enableLayers ?? true);
this.featureSwitchAddNew = featSw("fs-add-new", (layoutToUse) => layoutToUse?.enableAddNewPoints ?? true);
this.featureSwitchWelcomeMessage = featSw("fs-welcome-message", () => true);
this.featureSwitchIframe = featSw("fs-iframe", () => false);
this.featureSwitchMoreQuests = featSw("fs-more-quests", (layoutToUse) => layoutToUse?.enableMoreQuests ?? true);
this.featureSwitchShareScreen = featSw("fs-share-screen", (layoutToUse) => layoutToUse?.enableShareScreen ?? true);
this.featureSwitchGeolocation = featSw("fs-geolocation", (layoutToUse) => layoutToUse?.enableGeolocation ?? true);
"Disables/Enables the user information pill (userbadge) at the top left. Disabling this disables logging in and thus disables editing all together, effectively putting MapComplete into read-only mode.");
this.featureSwitchSearch = featSw("fs-search", (layoutToUse) => layoutToUse?.enableSearch ?? true,
"Disables/Enables the search bar");
this.featureSwitchLayers = featSw("fs-layers", (layoutToUse) => layoutToUse?.enableLayers ?? true,
"Disables/Enables the layer control");
this.featureSwitchAddNew = featSw("fs-add-new", (layoutToUse) => layoutToUse?.enableAddNewPoints ?? true,
"Disables/Enables the 'add new feature'-popup. (A theme without presets might not have it in the first place)");
this.featureSwitchWelcomeMessage = featSw("fs-welcome-message", () => true,
"Disables/enables the help menu or welcome message");
this.featureSwitchIframe = featSw("fs-iframe", () => false,
"Disables/Enables the iframe-popup");
this.featureSwitchMoreQuests = featSw("fs-more-quests", (layoutToUse) => layoutToUse?.enableMoreQuests ?? true,
"Disables/Enables the 'More Quests'-tab in the welcome message");
this.featureSwitchShareScreen = featSw("fs-share-screen", (layoutToUse) => layoutToUse?.enableShareScreen ?? true,
"Disables/Enables the 'Share-screen'-tab in the welcome message");
this.featureSwitchGeolocation = featSw("fs-geolocation", (layoutToUse) => layoutToUse?.enableGeolocation ?? true,
"Disables/Enables the geolocation button");
const testParam = QueryParameters.GetQueryParameter("test", "false").data;
const testParam = QueryParameters.GetQueryParameter("test", "false",
"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").data;
this.osmConnection = new OsmConnection(
testParam === "true",
QueryParameters.GetQueryParameter("oauth_token", undefined),
QueryParameters.GetQueryParameter("oauth_token", undefined,
"Used to complete the login"),
layoutToUse.id,
true
);

View file

@ -42,6 +42,9 @@ export default class DeleteImage extends UIElement {
}
InnerRender(): string {
if(!State.state.featureSwitchUserbadge.data){
return "";
}
const value = this.tags.data[this.key];
if (value === undefined || value === "") {

View file

@ -51,6 +51,10 @@ export class ImageUploadFlow extends UIElement {
}
InnerRender(): string {
if(!State.state.featureSwitchUserbadge.data){
return "";
}
const t = Translations.t.image;
if (State.state.osmConnection.userDetails === undefined) {

View file

@ -9,25 +9,11 @@ import {SubstitutedTranslation} from "../SpecialVisualizations";
export default class TagRenderingAnswer extends UIElement {
private _tags: UIEventSource<any>;
private _configuration: TagRenderingConfig;
private _content: UIElement;
constructor(tags: UIEventSource<any>, configuration: TagRenderingConfig) {
super(tags);
this._tags = tags;
this._configuration = configuration;
const self = this;
tags.addCallbackAndRun(tags => {
if (tags === undefined) {
self._content = undefined
return;
}
const tr = this._configuration.GetRenderValue(tags);
if (tr === undefined) {
self._content = undefined
return
}
self._content = new SubstitutedTranslation(tr, self._tags)
})
}
InnerRender(): string {
@ -36,10 +22,16 @@ export default class TagRenderingAnswer extends UIElement {
return "";
}
}
if(this._content === undefined){
const tags = this._tags.data;
if (tags === undefined) {
return "";
}
return this._content.Render();
const tr = this._configuration.GetRenderValue(tags);
if (tr === undefined) {
return "";
}
return new SubstitutedTranslation(tr, this._tags).Render();
}
}

View file

@ -156,8 +156,8 @@
"key": "surveillance:type"
},
"render": {
"en": " Surveills a {surveillance:type}",
"nl": "Bewaakt een {surveillance:type}"
"en": " Surveills a {surveillance:zone}",
"nl": "Bewaakt een {surveillance:zone}"
},
"mappings": [
{
@ -193,6 +193,28 @@
"nl": "Bewaakt een ingang"
}
},
{
"if": {
"and": [
"surveillance:zone=corridor"
]
},
"then": {
"en": "Surveills a corridor",
"nl": "Bewaakt een gang"
}
},
{
"if": {
"and": [
"surveillance:zone=public_transport_platform"
]
},
"then": {
"en": "Surveills a public tranport platform",
"nl": "Bewaakt een perron of bushalte"
}
},
{
"if": {
"and": [

View file

@ -4,7 +4,6 @@ import {InitUiElements} from "./InitUiElements";
import {QueryParameters} from "./Logic/Web/QueryParameters";
import {UIEventSource} from "./Logic/UIEventSource";
import * as $ from "jquery";
import SharedLayers from "./Customizations/SharedLayers";
import LayoutConfig from "./Customizations/JSON/LayoutConfig";
let defaultLayout = "bookcases"
@ -54,23 +53,7 @@ if (path !== "index.html" && path !== "") {
defaultLayout = path.substr(0, path.length - 5);
console.log("Using layout", defaultLayout);
}
// Run over all questsets. If a part of the URL matches a searched-for part in the layout, it'll take that as the default
for (const k in AllKnownLayouts.allSets) {
const layout : LayoutConfig= AllKnownLayouts.allSets[k];
const possibleParts = (layout.locationContains ?? []);
for (const locationMatch of possibleParts) {
if (locationMatch === "") {
continue
}
if (window.location.href.toLowerCase().indexOf(locationMatch.toLowerCase()) >= 0) {
defaultLayout = layout.name;
}
}
}
defaultLayout = QueryParameters.GetQueryParameter("layout", defaultLayout).data;
defaultLayout = QueryParameters.GetQueryParameter("layout", defaultLayout,"The layout to load into MapComplete").data;
let layoutToUse: LayoutConfig = AllKnownLayouts.allSets[defaultLayout.toLowerCase()] ?? AllKnownLayouts["all"];
@ -118,3 +101,4 @@ if (layoutFromBase64.startsWith("wiki:")) {
InitUiElements.InitAll(layoutToUse, layoutFromBase64, testing, defaultLayout);
}
// console.log(QueryParameters.GenerateQueryParameterDocs())