Merge branch 'develop' into feature/velopark

This commit is contained in:
Pieter Vander Vennet 2024-01-19 00:34:58 +01:00
commit 59e76b9c6f
30 changed files with 963 additions and 654 deletions

View file

@ -1,26 +0,0 @@
import BaseUIElement from "../BaseUIElement"
import { VariableUiElement } from "./VariableUIElement"
import { Stores } from "../../Logic/UIEventSource"
import Loading from "./Loading"
export default class AsyncLazy extends BaseUIElement {
private readonly _f: () => Promise<BaseUIElement>
constructor(f: () => Promise<BaseUIElement>) {
super()
this._f = f
}
protected InnerConstructElement(): HTMLElement {
// The caching of the BaseUIElement will guarantee that _f will only be called once
return new VariableUiElement(
Stores.FromPromise(this._f()).map((el) => {
if (el === undefined) {
return new Loading()
}
return el
})
).ConstructElement()
}
}

View file

@ -1,50 +0,0 @@
import BaseUIElement from "../BaseUIElement"
import { UIEventSource } from "../../Logic/UIEventSource"
import { VariableUiElement } from "./VariableUIElement"
import Combine from "./Combine"
import Locale from "../i18n/Locale"
import { Utils } from "../../Utils"
export default class FilteredCombine extends VariableUiElement {
/**
* Only shows item matching the search
* If predicate of an item is undefined, it will be filtered out as soon as a non-null or non-empty search term is given
* @param entries
* @param searchedValue
* @param options
*/
constructor(
entries: {
element: BaseUIElement | string
predicate?: (s: string) => boolean
}[],
searchedValue: UIEventSource<string>,
options?: {
onEmpty?: BaseUIElement | string
innerClasses: string
}
) {
entries = Utils.NoNull(entries)
super(
searchedValue.map(
(searchTerm) => {
if (searchTerm === undefined || searchTerm === "") {
return new Combine(entries.map((e) => e.element)).SetClass(
options?.innerClasses ?? ""
)
}
const kept = entries.filter(
(entry) => entry?.predicate !== undefined && entry.predicate(searchTerm)
)
if (kept.length === 0) {
return options?.onEmpty
}
return new Combine(kept.map((entry) => entry.element)).SetClass(
options?.innerClasses ?? ""
)
},
[Locale.language]
)
)
}
}

View file

@ -2,13 +2,14 @@
import ToSvelte from "./ToSvelte.svelte"
import Svg from "../../Svg"
import { twMerge } from "tailwind-merge"
import Loading from "../../assets/svg/Loading.svelte"
export let cls: string = undefined
</script>
<div class={twMerge("flex p-1 pl-2", cls)}>
<div class="min-w-6 h-6 w-6 shrink-0 animate-spin self-center">
<ToSvelte construct={Svg.loading_svg()} />
<Loading/>
</div>
<div class="ml-2">
<slot />

View file

@ -1,9 +1,6 @@
import BaseUIElement from "../BaseUIElement"
import { Store, UIEventSource } from "../../Logic/UIEventSource"
import { UIElement } from "../UIElement"
import { VariableUiElement } from "./VariableUIElement"
import Lazy from "./Lazy"
import Loading from "./Loading"
import SvelteUIElement from "./SvelteUIElement"
import SubtleLink from "./SubtleLink.svelte"
import Translations from "../i18n/Translations"

View file

@ -21,8 +21,8 @@
export let layer: LayerConfig
export let linkable = true
let isLinked = Object.values(tags.data).some((v) => image.pictureUrl === v)
let targetValue = Object.values(image.osmTags)[0]
let isLinked = new UIEventSource(Object.values(tags.data).some((v) => targetValue === v))
const t = Translations.t.image.nearby
const providedImage: ProvidedImage = {
url: image.thumbUrl ?? image.pictureUrl,
@ -33,10 +33,11 @@
id: Object.values(image.osmTags)[0],
}
$: {
function applyLink(isLinked :boolean) {
console.log("Applying linked image", isLinked, targetValue)
const currentTags = tags.data
const key = Object.keys(image.osmTags)[0]
const url = image.osmTags[key]
const url = targetValue
if (isLinked) {
const action = new LinkImageAction(currentTags.id, key, url, tags, {
theme: tags.data._orig_theme ?? state.layout.id,
@ -56,6 +57,7 @@
}
}
}
isLinked.addCallback(isLinked => applyLink(isLinked))
</script>
<div class="flex w-fit shrink-0 flex-col">
@ -68,7 +70,7 @@
</div>
{#if linkable}
<label>
<input bind:checked={isLinked} type="checkbox" />
<input bind:checked={$isLinked} type="checkbox" />
<SpecialTranslation t={t.link} {tags} {state} {layer} {feature} />
</label>
{/if}

View file

@ -35,6 +35,10 @@ export default class PhoneValidator extends Validator {
if (country !== undefined) {
countryCode = country()?.toUpperCase()
}
if (this.isShortCode(str, countryCode)) {
return true
}
return parsePhoneNumberFromString(str, countryCode)?.isValid() ?? false
}
@ -46,9 +50,28 @@ export default class PhoneValidator extends Validator {
if (country) {
countryCode = country()
}
if (this.isShortCode(str, countryCode?.toUpperCase())) {
return str
}
return parsePhoneNumberFromString(
str,
countryCode?.toUpperCase() as any
)?.formatInternational()
}
/**
* Indicates if the given string is a special 'short code' valid in the given country
* see https://nl.wikipedia.org/wiki/Short_code
* @param str a possible phone number
* @param country the upper case, two-letter code for a country
* @private
*/
private isShortCode(str: string, country: string) {
if (country == "BE" && str.length === 4 && str.match(/[0-9]{4}/)) {
return true
}
if (country == "NL" && str.length === 4 && str.match(/14[0-9]{3}/)) {
return true
}
}
}

View file

@ -12,6 +12,7 @@ import { Feature, Point } from "geojson"
import SvelteUIElement from "../Base/SvelteUIElement"
import Confirm from "../../assets/svg/Confirm.svelte"
import Relocation from "../../assets/svg/Relocation.svelte"
import Location from "../../assets/svg/Location.svelte"
export interface MoveReason {
text: Translation | string
@ -62,7 +63,7 @@ export class MoveWizardState {
reasons.push({
text: t.reasons.reasonInaccurate,
invitingText: t.inviteToMove.reasonInaccurate,
icon: new SvelteUIElement(Confirm),
icon: new SvelteUIElement(Location),
changesetCommentValue: "improve_accuracy",
lockBounds: true,
includeSearch: false,

View file

@ -1,6 +1,5 @@
import Combine from "../../Base/Combine"
import BaseUIElement from "../../BaseUIElement"
import Svg from "../../../Svg"
import Link from "../../Base/Link"
import { FixedUiElement } from "../../Base/FixedUiElement"
import Translations from "../../i18n/Translations"
@ -11,6 +10,10 @@ import { Stores, UIEventSource } from "../../../Logic/UIEventSource"
import { OsmConnection } from "../../../Logic/Osm/OsmConnection"
import { VariableUiElement } from "../../Base/VariableUIElement"
import { SpecialVisualizationState } from "../../SpecialVisualization"
import SvelteUIElement from "../../Base/SvelteUIElement"
import Note from "../../../assets/svg/Note.svelte"
import Resolved from "../../../assets/svg/Resolved.svelte"
import Speech_bubble from "../../../assets/svg/Speech_bubble.svelte"
export default class NoteCommentElement extends Combine {
constructor(
@ -32,11 +35,11 @@ export default class NoteCommentElement extends Combine {
let actionIcon: BaseUIElement
if (comment.action === "opened" || comment.action === "reopened") {
actionIcon = Svg.note_svg()
actionIcon = new SvelteUIElement(Note)
} else if (comment.action === "closed") {
actionIcon = Svg.resolved_svg()
actionIcon = new SvelteUIElement(Resolved)
} else {
actionIcon = Svg.speech_bubble_svg()
actionIcon = new SvelteUIElement(Speech_bubble)
}
let user: BaseUIElement

View file

@ -6,7 +6,6 @@
import type { SpecialVisualizationState } from "../../SpecialVisualization"
import type { Feature } from "geojson"
import { Store, UIEventSource } from "../../../Logic/UIEventSource"
import { onDestroy } from "svelte"
import LayerConfig from "../../../Models/ThemeConfig/LayerConfig"
import { twMerge } from "tailwind-merge"
@ -24,7 +23,7 @@
throw "Config is undefined in tagRenderingAnswer"
}
let trs: Store<{ then: Translation; icon?: string; iconClass?: string }[]> = tags.mapD((tags) =>
Utils.NoNull(config?.GetRenderValues(tags))
Utils.NoNull(config?.GetRenderValues(tags)),
)
</script>

View file

@ -29,9 +29,6 @@ export default class Zoomcontrol {
this._allowZooming.addCallback((allowed) => {
this.apply(allowed ? Zoomcontrol.initialValue : Zoomcontrol.noZoom)
})
Stores.Chronic(1000).addCallback((_) =>
console.log(this.viewportElement.getAttribute("content"))
)
}
private _resetZoom() {