forked from MapComplete/MapComplete
Full code cleanup
This commit is contained in:
parent
3a4a2a2016
commit
fa971ffbbf
300 changed files with 16352 additions and 19284 deletions
|
@ -27,8 +27,8 @@ export default class AddNewMarker extends Combine {
|
|||
}
|
||||
}
|
||||
}
|
||||
if(icons.length === 0){
|
||||
return undefined
|
||||
if (icons.length === 0) {
|
||||
return undefined
|
||||
}
|
||||
if (icons.length === 1) {
|
||||
return icons[0]
|
||||
|
|
|
@ -1,20 +1,19 @@
|
|||
import {SubtleButton} from "../Base/SubtleButton";
|
||||
import Combine from "../Base/Combine";
|
||||
import Svg from "../../Svg";
|
||||
import Translations from "../i18n/Translations";
|
||||
import BaseUIElement from "../BaseUIElement";
|
||||
|
||||
export default class BackToIndex extends SubtleButton {
|
||||
|
||||
constructor(message? : string | BaseUIElement) {
|
||||
|
||||
constructor(message?: string | BaseUIElement) {
|
||||
super(
|
||||
Svg.back_svg().SetStyle("height: 1.5rem;"),
|
||||
message ?? Translations.t.general.backToMapcomplete,
|
||||
message ?? Translations.t.general.backToMapcomplete,
|
||||
{
|
||||
url: "index.html"
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -84,7 +84,7 @@ class SingleLayerSelectionButton extends Toggle {
|
|||
previousLayer.setData(previousLayer.data ?? available.data)
|
||||
options.currentBackground.setData(previousLayer.data)
|
||||
})
|
||||
|
||||
|
||||
options.currentBackground.addCallbackAndRunD(background => {
|
||||
if (background.category === options.preferredType) {
|
||||
previousLayer.setData(background)
|
||||
|
@ -103,9 +103,9 @@ class SingleLayerSelectionButton extends Toggle {
|
|||
// The previously used layer doesn't match the current layer -> no need to switch
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Is the previous layer still valid? If so, we don't bother to switch
|
||||
if(previousLayer.data.feature === null || GeoOperations.inside(locationControl.data, previousLayer.data.feature)){
|
||||
if (previousLayer.data.feature === null || GeoOperations.inside(locationControl.data, previousLayer.data.feature)) {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -22,15 +22,15 @@ import Constants from "../../Models/Constants";
|
|||
import ContributorCount from "../../Logic/ContributorCount";
|
||||
|
||||
export class OpenIdEditor extends VariableUiElement {
|
||||
constructor(state : {locationControl: UIEventSource<Loc>}, iconStyle? : string, objectId?: string) {
|
||||
constructor(state: { locationControl: UIEventSource<Loc> }, iconStyle?: string, objectId?: string) {
|
||||
const t = Translations.t.general.attribution
|
||||
super(state.locationControl.map(location => {
|
||||
let elementSelect = "";
|
||||
if(objectId !== undefined){
|
||||
const parts = objectId.split("/")
|
||||
if (objectId !== undefined) {
|
||||
const parts = objectId.split("/")
|
||||
const tp = parts[0]
|
||||
if(parts.length === 2 && !isNaN(Number(parts[1])) && (tp === "node" || tp === "way" || tp === "relation")){
|
||||
elementSelect = "&"+ tp+"="+parts[1]
|
||||
if (parts.length === 2 && !isNaN(Number(parts[1])) && (tp === "node" || tp === "way" || tp === "relation")) {
|
||||
elementSelect = "&" + tp + "=" + parts[1]
|
||||
}
|
||||
}
|
||||
const idLink = `https://www.openstreetmap.org/edit?editor=id${elementSelect}#map=${location?.zoom ?? 0}/${location?.lat ?? 0}/${location?.lon ?? 0}`
|
||||
|
@ -41,9 +41,9 @@ export class OpenIdEditor extends VariableUiElement {
|
|||
}
|
||||
|
||||
export class OpenMapillary extends VariableUiElement {
|
||||
constructor(state : {locationControl: UIEventSource<Loc>}, iconStyle? : string) {
|
||||
constructor(state: { locationControl: UIEventSource<Loc> }, iconStyle?: string) {
|
||||
const t = Translations.t.general.attribution
|
||||
super( state.locationControl.map(location => {
|
||||
super(state.locationControl.map(location => {
|
||||
const mapillaryLink = `https://www.mapillary.com/app/?focus=map&lat=${location?.lat ?? 0}&lng=${location?.lon ?? 0}&z=${Math.max((location?.zoom ?? 2) - 1, 1)}`
|
||||
return new SubtleButton(Svg.mapillary_black_ui().SetStyle(iconStyle), t.openMapillary, {
|
||||
url: mapillaryLink,
|
||||
|
@ -55,13 +55,13 @@ export class OpenMapillary extends VariableUiElement {
|
|||
|
||||
export class OpenJosm extends Combine {
|
||||
|
||||
constructor(state : {osmConnection: OsmConnection, currentBounds: UIEventSource<BBox>,}, iconStyle? : string) {
|
||||
const t = Translations.t.general.attribution
|
||||
|
||||
constructor(state: { osmConnection: OsmConnection, currentBounds: UIEventSource<BBox>, }, iconStyle?: string) {
|
||||
const t = Translations.t.general.attribution
|
||||
|
||||
const josmState = new UIEventSource<string>(undefined)
|
||||
// Reset after 15s
|
||||
josmState.stabilized(15000).addCallbackD(_ => josmState.setData(undefined))
|
||||
|
||||
|
||||
const stateIndication = new VariableUiElement(josmState.map(state => {
|
||||
if (state === undefined) {
|
||||
return undefined
|
||||
|
@ -72,23 +72,23 @@ export class OpenJosm extends Combine {
|
|||
}
|
||||
return t.josmNotOpened.SetClass("alert")
|
||||
}));
|
||||
|
||||
const toggle = new Toggle(
|
||||
new SubtleButton(Svg.josm_logo_ui().SetStyle(iconStyle), t.editJosm).onClick(() => {
|
||||
const bounds: any = state.currentBounds.data;
|
||||
if (bounds === undefined) {
|
||||
return undefined
|
||||
}
|
||||
const top = bounds.getNorth();
|
||||
const bottom = bounds.getSouth();
|
||||
const right = bounds.getEast();
|
||||
const left = bounds.getWest();
|
||||
const josmLink = `http://127.0.0.1:8111/load_and_zoom?left=${left}&right=${right}&top=${top}&bottom=${bottom}`
|
||||
Utils.download(josmLink).then(answer => josmState.setData(answer.replace(/\n/g, '').trim())).catch(_ => josmState.setData("ERROR"))
|
||||
}), undefined, state.osmConnection.userDetails.map(ud => ud.loggedIn && ud.csCount >= Constants.userJourney.historyLinkVisible))
|
||||
|
||||
const toggle = new Toggle(
|
||||
new SubtleButton(Svg.josm_logo_ui().SetStyle(iconStyle), t.editJosm).onClick(() => {
|
||||
const bounds: any = state.currentBounds.data;
|
||||
if (bounds === undefined) {
|
||||
return undefined
|
||||
}
|
||||
const top = bounds.getNorth();
|
||||
const bottom = bounds.getSouth();
|
||||
const right = bounds.getEast();
|
||||
const left = bounds.getWest();
|
||||
const josmLink = `http://127.0.0.1:8111/load_and_zoom?left=${left}&right=${right}&top=${top}&bottom=${bottom}`
|
||||
Utils.download(josmLink).then(answer => josmState.setData(answer.replace(/\n/g, '').trim())).catch(_ => josmState.setData("ERROR"))
|
||||
}), undefined, state.osmConnection.userDetails.map(ud => ud.loggedIn && ud.csCount >= Constants.userJourney.historyLinkVisible))
|
||||
|
||||
super([stateIndication, toggle]);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -112,7 +112,7 @@ export default class CopyrightPanel extends Combine {
|
|||
|
||||
const t = Translations.t.general.attribution
|
||||
const layoutToUse = state.layoutToUse
|
||||
const iconStyle = "height: 1.5rem; width: auto"
|
||||
const iconStyle = "height: 1.5rem; width: auto"
|
||||
const actionButtons = [
|
||||
new SubtleButton(Svg.liberapay_ui().SetStyle(iconStyle), t.donate, {
|
||||
url: "https://liberapay.com/pietervdvn/",
|
||||
|
@ -139,11 +139,11 @@ export default class CopyrightPanel extends Combine {
|
|||
maintainer = Translations.t.general.attribution.themeBy.Subs({author: layoutToUse.maintainer})
|
||||
}
|
||||
|
||||
const contributions = new ContributorCount(state).Contributors
|
||||
|
||||
const contributions = new ContributorCount(state).Contributors
|
||||
|
||||
super([
|
||||
Translations.t.general.attribution.attributionContent,
|
||||
new FixedUiElement("MapComplete "+Constants.vNumber).SetClass("font-bold"),
|
||||
new FixedUiElement("MapComplete " + Constants.vNumber).SetClass("font-bold"),
|
||||
maintainer,
|
||||
new Combine(actionButtons).SetClass("block w-full"),
|
||||
new FixedUiElement(layoutToUse.credits),
|
||||
|
|
|
@ -33,12 +33,12 @@ export default class FeaturedMessage extends Combine {
|
|||
|
||||
public static WelcomeMessages(): { start_date: Date, end_date: Date, message: string, featured_theme?: string }[] {
|
||||
const all_messages: { start_date: Date, end_date: Date, message: string, featured_theme?: string }[] = []
|
||||
|
||||
const themesById = new Map<string, {id: string, title: any, shortDescription: any}>();
|
||||
|
||||
const themesById = new Map<string, { id: string, title: any, shortDescription: any }>();
|
||||
for (const theme of themeOverview["default"]) {
|
||||
themesById.set(theme.id, theme);
|
||||
}
|
||||
|
||||
|
||||
for (const i in welcome_messages) {
|
||||
if (isNaN(Number(i))) {
|
||||
continue
|
||||
|
@ -78,9 +78,9 @@ export default class FeaturedMessage extends Combine {
|
|||
const msg = new FixedUiElement(welcome_message.message).SetClass("link-underline font-lg")
|
||||
els.push(new Combine([title, msg]).SetClass("m-4"))
|
||||
if (welcome_message.featured_theme !== undefined) {
|
||||
|
||||
|
||||
const theme = themeOverview["default"].filter(th => th.id === welcome_message.featured_theme)[0];
|
||||
|
||||
|
||||
els.push(MoreScreen.createLinkButton({}, theme)
|
||||
.SetClass("m-4 self-center md:w-160")
|
||||
.SetStyle("height: min-content;"))
|
||||
|
|
|
@ -145,14 +145,14 @@ export default class FilterView extends VariableUiElement {
|
|||
if (layer.filters.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
||||
const toShow : BaseUIElement [] = []
|
||||
|
||||
|
||||
const toShow: BaseUIElement [] = []
|
||||
|
||||
for (const filter of layer.filters) {
|
||||
|
||||
|
||||
const [ui, actualTags] = FilterView.createFilter(filter)
|
||||
|
||||
|
||||
ui.SetClass("mt-3")
|
||||
toShow.push(ui)
|
||||
actualTags.addCallback(tagsToFilterFor => {
|
||||
|
@ -161,15 +161,15 @@ export default class FilterView extends VariableUiElement {
|
|||
})
|
||||
flayer.appliedFilters.map(dict => dict.get(filter.id))
|
||||
.addCallbackAndRun(filters => actualTags.setData(filters))
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
return new Combine(toShow)
|
||||
.SetClass("flex flex-col ml-8 bg-gray-300 rounded-xl p-2")
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Filter which uses one or more textfields
|
||||
private static createFilterWithFields(filterConfig: FilterConfig): [BaseUIElement, UIEventSource<FilterState>] {
|
||||
|
||||
|
@ -191,7 +191,7 @@ export default class FilterView extends VariableUiElement {
|
|||
allValid = allValid.map(previous => previous && field.IsValid(stable.data) && stable.data !== "", [stable])
|
||||
}
|
||||
const tr = new SubstitutedTranslation(filter.question, new UIEventSource<any>({id: filterConfig.id}), State.state, mappings)
|
||||
const trigger : UIEventSource<FilterState>= allValid.map(isValid => {
|
||||
const trigger: UIEventSource<FilterState> = allValid.map(isValid => {
|
||||
if (!isValid) {
|
||||
return undefined
|
||||
}
|
||||
|
@ -204,9 +204,9 @@ export default class FilterView extends VariableUiElement {
|
|||
}
|
||||
|
||||
for (const key in props) {
|
||||
v = (<string>v).replace("{"+key+"}", props[key])
|
||||
v = (<string>v).replace("{" + key + "}", props[key])
|
||||
}
|
||||
|
||||
|
||||
return v
|
||||
}
|
||||
)
|
||||
|
@ -216,11 +216,11 @@ export default class FilterView extends VariableUiElement {
|
|||
state: JSON.stringify(props)
|
||||
}
|
||||
}, [properties])
|
||||
|
||||
|
||||
return [tr, trigger];
|
||||
}
|
||||
|
||||
private static createCheckboxFilter(filterConfig: FilterConfig): [BaseUIElement, UIEventSource<FilterState>] {
|
||||
|
||||
private static createCheckboxFilter(filterConfig: FilterConfig): [BaseUIElement, UIEventSource<FilterState>] {
|
||||
let option = filterConfig.options[0];
|
||||
|
||||
const icon = Svg.checkbox_filled_svg().SetClass("block mr-2 w-6");
|
||||
|
@ -233,21 +233,25 @@ export default class FilterView extends VariableUiElement {
|
|||
.ToggleOnClick()
|
||||
.SetClass("block m-1")
|
||||
|
||||
return [toggle, toggle.isEnabled.map(enabled => enabled ? {currentFilter: option.osmTags, state: "true"} : undefined, [],
|
||||
return [toggle, toggle.isEnabled.map(enabled => enabled ? {
|
||||
currentFilter: option.osmTags,
|
||||
state: "true"
|
||||
} : undefined, [],
|
||||
f => f !== undefined)
|
||||
]
|
||||
}
|
||||
|
||||
private static createMultiFilter(filterConfig: FilterConfig): [BaseUIElement, UIEventSource<FilterState>] {
|
||||
|
||||
let options = filterConfig.options;
|
||||
|
||||
const values : FilterState[] = options.map((f, i) => ({
|
||||
const values: FilterState[] = options.map((f, i) => ({
|
||||
currentFilter: f.osmTags, state: i
|
||||
}))
|
||||
let filterPicker : InputElement<number>
|
||||
|
||||
if(options.length <= 6){
|
||||
filterPicker = new RadioButton(
|
||||
let filterPicker: InputElement<number>
|
||||
|
||||
if (options.length <= 6) {
|
||||
filterPicker = new RadioButton(
|
||||
options.map(
|
||||
(option, i) =>
|
||||
new FixedInputElement(option.question.Clone().SetClass("block"), i)
|
||||
|
@ -256,25 +260,26 @@ export default class FilterView extends VariableUiElement {
|
|||
dontStyle: true
|
||||
}
|
||||
);
|
||||
}else{
|
||||
} else {
|
||||
filterPicker = new DropDown("", options.map((option, i) => ({
|
||||
value: i, shown: option.question.Clone()
|
||||
})))
|
||||
}
|
||||
|
||||
|
||||
return [filterPicker,
|
||||
filterPicker.GetValue().map(
|
||||
i => values[i],
|
||||
[],
|
||||
selected => {
|
||||
const v = selected?.state
|
||||
if(v === undefined || typeof v === "string"){
|
||||
if (v === undefined || typeof v === "string") {
|
||||
return undefined
|
||||
}
|
||||
return v
|
||||
}
|
||||
)]
|
||||
}
|
||||
|
||||
private static createFilter(filterConfig: FilterConfig): [BaseUIElement, UIEventSource<FilterState>] {
|
||||
|
||||
if (filterConfig.options[0].fields.length > 0) {
|
||||
|
@ -283,7 +288,7 @@ export default class FilterView extends VariableUiElement {
|
|||
|
||||
|
||||
if (filterConfig.options.length === 1) {
|
||||
return FilterView.createCheckboxFilter(filterConfig)
|
||||
return FilterView.createCheckboxFilter(filterConfig)
|
||||
}
|
||||
|
||||
return FilterView.createMultiFilter(filterConfig)
|
||||
|
|
|
@ -92,7 +92,7 @@ export default class FullWelcomePaneWithTabs extends ScrollableFullScreen {
|
|||
)
|
||||
}
|
||||
tabs.push(copyright)
|
||||
|
||||
|
||||
const privacy = {
|
||||
header: Svg.eye_svg(),
|
||||
content: new PrivacyPolicy()
|
||||
|
|
|
@ -22,12 +22,12 @@ export default class Histogram<T> extends VariableUiElement {
|
|||
constructor(values: UIEventSource<string[]>,
|
||||
title: string | BaseUIElement,
|
||||
countTitle: string | BaseUIElement,
|
||||
options?:{
|
||||
assignColor?: (t0: string) => string,
|
||||
options?: {
|
||||
assignColor?: (t0: string) => string,
|
||||
sortMode?: "name" | "name-rev" | "count" | "count-rev"
|
||||
}
|
||||
) {
|
||||
const sortMode = new UIEventSource<"name" | "name-rev" | "count" | "count-rev">(options?.sortMode ??"name")
|
||||
const sortMode = new UIEventSource<"name" | "name-rev" | "count" | "count-rev">(options?.sortMode ?? "name")
|
||||
const sortName = new VariableUiElement(sortMode.map(m => {
|
||||
switch (m) {
|
||||
case "name":
|
||||
|
|
|
@ -50,7 +50,7 @@ export default class LeftControls extends Combine {
|
|||
}
|
||||
return new Lazy(() => {
|
||||
const tagsSource = state.allElements.getEventSourceById(feature.properties.id)
|
||||
return new FeatureInfoBox(tagsSource, currentViewFL.layerDef,state, "currentview", guiState.currentViewControlIsOpened)
|
||||
return new FeatureInfoBox(tagsSource, currentViewFL.layerDef, state, "currentview", guiState.currentViewControlIsOpened)
|
||||
.SetClass("md:floating-element-width")
|
||||
})
|
||||
}))
|
||||
|
|
|
@ -10,26 +10,26 @@ export default class LicensePicker extends DropDown<string> {
|
|||
private static readonly ccbysa = "CC-BY-SA 4.0"
|
||||
private static readonly ccby = "CC-BY 4.0"
|
||||
|
||||
constructor(state: {osmConnection: OsmConnection}) {
|
||||
constructor(state: { osmConnection: OsmConnection }) {
|
||||
super(Translations.t.image.willBePublished.Clone(),
|
||||
[
|
||||
{value:LicensePicker. cc0, shown: Translations.t.image.cco.Clone()},
|
||||
{value:LicensePicker. ccbysa, shown: Translations.t.image.ccbs.Clone()},
|
||||
{value: LicensePicker. ccby, shown: Translations.t.image.ccb.Clone()}
|
||||
{value: LicensePicker.cc0, shown: Translations.t.image.cco.Clone()},
|
||||
{value: LicensePicker.ccbysa, shown: Translations.t.image.ccbs.Clone()},
|
||||
{value: LicensePicker.ccby, shown: Translations.t.image.ccb.Clone()}
|
||||
],
|
||||
state?.osmConnection?.GetPreference("pictures-license") ?? new UIEventSource<string>("CC0")
|
||||
)
|
||||
this.SetClass("flex flex-col sm:flex-row").SetStyle("float:left");
|
||||
}
|
||||
|
||||
public static LicenseExplanations() : Map<string, Translation>{
|
||||
public static LicenseExplanations(): Map<string, Translation> {
|
||||
let dict = new Map<string, Translation>();
|
||||
|
||||
dict.set(LicensePicker. cc0, Translations.t.image.ccoExplanation)
|
||||
dict.set(LicensePicker. ccby, Translations.t.image.ccbExplanation)
|
||||
dict.set(LicensePicker. ccbysa, Translations.t.image.ccbsExplanation)
|
||||
|
||||
dict.set(LicensePicker.cc0, Translations.t.image.ccoExplanation)
|
||||
dict.set(LicensePicker.ccby, Translations.t.image.ccbExplanation)
|
||||
dict.set(LicensePicker.ccbysa, Translations.t.image.ccbsExplanation)
|
||||
|
||||
return dict
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -198,7 +198,7 @@ export default class MoreScreen extends Combine {
|
|||
}
|
||||
return button;
|
||||
})
|
||||
|
||||
|
||||
const professional = MoreScreen.CreateProffessionalSerivesButton();
|
||||
const customGeneratorLink = MoreScreen.createCustomGeneratorButton(state)
|
||||
buttons.splice(0, 0, customGeneratorLink, professional);
|
||||
|
|
|
@ -94,7 +94,7 @@ export default class SimpleAddUI extends Toggle {
|
|||
return presetsOverview
|
||||
}
|
||||
|
||||
function confirm(tags:any[], location: {lat: number, lon:number}, snapOntoWayId?: string) {
|
||||
function confirm(tags: any[], location: { lat: number, lon: number }, snapOntoWayId?: string) {
|
||||
if (snapOntoWayId === undefined) {
|
||||
createNewPoint(tags, location, undefined)
|
||||
} else {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue