Merge develop

This commit is contained in:
Pieter Vander Vennet 2025-01-29 21:19:11 +01:00
commit 3fe1f39c46
457 changed files with 6866 additions and 218533 deletions

View file

@ -2,17 +2,20 @@
import { Store, UIEventSource } from "../../Logic/UIEventSource"
import { Tiles } from "../../Models/TileRange"
import { Utils } from "../../Utils"
import global_community from "../../assets/community_index_global_resources.json"
import ContactLink from "./ContactLink.svelte"
import { GeoOperations } from "../../Logic/GeoOperations"
import Translations from "../i18n/Translations"
import ToSvelte from "../Base/ToSvelte.svelte"
import type { Feature, Geometry, GeometryCollection } from "@turf/turf"
import type { FeatureCollection, Polygon } from "geojson"
import type { CommunityResource } from "../../Logic/Web/CommunityIndex"
import Tr from "../Base/Tr.svelte"
import Constants from "../../Models/Constants"
import Loading from "../Base/Loading.svelte"
export let location: Store<{ lat: number; lon: number }>
const tileToFetch: Store<string> = location.mapD((l) => {
const t = Tiles.embedded_tile(l.lat, l.lon, 6)
return `https://raw.githubusercontent.com/pietervdvn/MapComplete-data/main/community_index/tile_${t.z}_${t.x}_${t.y}.geojson`
return Utils.SubstituteKeys(Constants.communityIndexHost + "tile_{z}_{x}_{y}.geojson", t)
})
const t = Translations.t.communityIndex
const resources = new UIEventSource<
@ -20,26 +23,39 @@
>([])
tileToFetch.addCallbackAndRun(async (url) => {
const data = await Utils.downloadJsonCached(url, 24 * 60 * 60)
const data = await Utils.downloadJsonCached<FeatureCollection<Polygon, {
nameEn: string,
resources: Record<string, CommunityResource>
}>>(url, 24 * 60 * 60)
if (data === undefined) {
return
}
resources.setData(data.features)
})
const filteredResources = resources.map(
const filteredResources = resources.mapD(
(features) =>
features.filter((f) => {
return GeoOperations.inside([location.data.lon, location.data.lat], f)
}),
features.filter((f) => GeoOperations.inside([location.data.lon, location.data.lat], f)),
[location]
)
const globalResources: UIEventSource<Record<string, CommunityResource>> = UIEventSource.FromPromise(Utils.downloadJsonCached<Record<string, CommunityResource>>(
Constants.communityIndexHost + "/global.json", 24 * 60 * 60 * 1000
))
</script>
<div>
<ToSvelte construct={t.intro} />
{#each $filteredResources as feature}
<ContactLink country={feature.properties} />
{/each}
<ContactLink country={{ resources: global_community, nameEn: "Global resources" }} />
<Tr t={t.intro} />
{#if $filteredResources === undefined}
<Loading />
{:else}
{#each $filteredResources as feature}
<ContactLink country={feature.properties} />
{/each}
{/if}
{#if $globalResources === undefined}
<Loading />
{:else}
<ContactLink country={{ resources: $globalResources, nameEn: "Global resources" }} />
{/if}
</div>

View file

@ -3,25 +3,20 @@
// The _properties_ of a community feature
import Locale from "../i18n/Locale.js"
import Translations from "../i18n/Translations"
import ToSvelte from "../Base/ToSvelte.svelte"
import * as native from "../../assets/language_native.json"
import { TypedTranslation } from "../i18n/Translation"
import Tr from "../Base/Tr.svelte"
import type { CommunityResource } from "../../Logic/Web/CommunityIndex"
import Constants from "../../Models/Constants"
const availableTranslationTyped: TypedTranslation<{ native: string }> =
Translations.t.communityIndex.available
const availableTranslation = availableTranslationTyped.OnEveryLanguage((s, ln) =>
s.replace("{native}", native[ln] ?? ln)
)
export let country: { resources; nameEn: string }
let resources: {
id: string
resolved: Record<string, string>
languageCodes: string[]
type: string
}[] = []
export let country: { resources: Record<string, CommunityResource>; nameEn: string }
let resources: CommunityResource[] = []
$: resources = Array.from(Object.values(country?.resources ?? {}))
const language = Locale.language
</script>
@ -33,16 +28,16 @@
<div class="link-underline my-4 flex items-center">
<img
class="m-2 h-8 w-8"
src={`https://raw.githubusercontent.com/pietervdvn/MapComplete-data/main/community_index/${resource.type}.svg`}
src={`${Constants.communityIndexHost}${resource.type}.svg`}
/>
<div class="flex flex-col">
<a
href={resource.resolved.url}
href={resource.resolved?.url}
target="_blank"
rel="noreferrer nofollow noopener"
class="font-bold"
>
{resource.resolved.name ?? resource.resolved.url}
{resource.resolved?.name ?? resource.resolved?.url}
</a>
{resource.resolved?.description}
{#if resource.languageCodes?.indexOf($language) >= 0}

View file

@ -1,106 +0,0 @@
<script lang="ts">
import { Store, UIEventSource } from "../../Logic/UIEventSource"
import type { SpecialVisualizationState } from "../SpecialVisualization"
import { Utils } from "../../Utils"
import Loading from "../../assets/svg/Loading.svelte"
export let tags: Store<Record<string, string>>
export let giggityUrl: string
export let state: SpecialVisualizationState
let name = $tags["name"]
let events: UIEventSource<
{
date: Date
start: string
duration: string
room: string
slug: string
url: string
title: string
track: string
type: string
language: string
abstract: string
description: string
persons: string
}[]
> = new UIEventSource(undefined)
async function loadXml() {
if (!name) {
console.log("Not fetching giggity events as name is", name, tags)
return
}
const xmlStr = await Utils.downloadAdvanced(giggityUrl)
console.log("Raw xml", xmlStr)
const parser = new DOMParser()
let doc = parser.parseFromString(xmlStr.content, "application/xml")
let days = Array.from(doc.documentElement.getElementsByTagName("day"))
let today = new Date().toISOString().split("T")[0]
const eventsToday = days.find((day) => day.getAttribute("date") === today)
console.log("Events today", eventsToday)
const childs = [
"date",
"start",
"duration",
"room",
"slug",
"url",
"title",
"track",
"type",
"language",
"abstract",
"description",
"persons",
]
const now = new Date().toISOString().split("T")[1].substring(0, 5)
let eventsList = []
for (const eventXml of Array.from(eventsToday.getElementsByTagName("event"))) {
const event: Record<string, string> = {}
for (const child of childs) {
const v = Array.from(eventXml.getElementsByTagName(child))
.map((xml) => xml.textContent)
.join("; ")
event[child] = v
}
if (!name.startsWith(event.room)) {
continue
}
if (now > event.start) {
continue
}
eventsList.push(event)
}
events.setData(eventsList)
}
loadXml()
</script>
{#if $events === undefined}
<Loading class="h-4">Loading giggity events from {giggityUrl}</Loading>
{:else if $events.length === 0}
<i>No upcoming events in this room</i>
{:else}
<div>
<h2>Upcoming events</h2>
{#each $events as event}
<div class="m-2 flex flex-col border border-dotted border-gray-200">
{#if event.url}
<h3><a href={event.url} target="_blank">{event.title}</a></h3>
{:else}
<h3>{event.title}</h3>
{/if}
<div><b>{event.start}</b></div>
<i>By {event.persons}</i>
<div>
{event.abstract}
</div>
{event.url}
</div>
{/each}
</div>
{/if}

View file

@ -21,7 +21,6 @@
import OpenIdEditor from "./OpenIdEditor.svelte"
import OpenJosm from "../Base/OpenJosm.svelte"
import MapillaryLink from "./MapillaryLink.svelte"
import Github from "../../assets/svg/Github.svelte"
import Bug from "../../assets/svg/Bug.svelte"
import CopyrightPanel from "./CopyrightPanel.svelte"
import CopyrightAllIcons from "./CopyrightAllIcons.svelte"
@ -53,6 +52,7 @@
import { UIEventSource } from "../../Logic/UIEventSource"
import MagnifyingGlassCircle from "@babeard/svelte-heroicons/mini/MagnifyingGlassCircle"
import { AndroidPolyfill } from "../../Logic/Web/AndroidPolyfill"
import Forgejo from "../../assets/svg/Forgejo.svelte"
export let state: ThemeViewState
let userdetails = state.osmConnection.userDetails
@ -126,17 +126,17 @@
</svelte:fragment>
<!-- All shown components are set by 'usersettings.json', which happily uses some special visualisations created specifically for it -->
<SelectedElementView
highlightedRendering={state.guistate.highlightedUserSetting}
layer={usersettingslayer}
selectedElement={{
type: "Feature",
properties: { id: "settings" },
geometry: { type: "Point", coordinates: [0, 0] },
}}
{state}
tags={state.userRelatedState.preferencesAsTags}
/>
<SelectedElementView
highlightedRendering={state.guistate.highlightedUserSetting}
layer={usersettingslayer}
selectedElement={{
type: "Feature",
properties: { id: "settings" },
geometry: { type: "Point", coordinates: [0, 0] },
}}
{state}
tags={state.userRelatedState.preferencesAsTags}
/>
</Page>
<LoginToggle {state} silentFail>
@ -208,7 +208,7 @@
{#if theme.official}
<a
class="flex"
href={"https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Themes/" +
href={"https://source.mapcomplete.org/MapComplete/MapComplete/src/branch/develop/Docs/Themes" +
theme.id +
".md"}
target="_blank"
@ -284,12 +284,16 @@
<Tr t={Translations.t.inspector.menu} />
</a>
<a class="flex" href="https://github.com/pietervdvn/MapComplete/" target="_blank">
<Github class="h-6 w-6" />
<a class="flex" href="https://source.mapcomplete.org/MapComplete/MapComplete/" target="_blank">
<Forgejo class="h-6 w-6" />
<Tr t={Translations.t.general.attribution.gotoSourceCode} />
</a>
<a class="flex" href="https://github.com/pietervdvn/MapComplete/issues" target="_blank">
<a
class="flex"
href="https://source.mapcomplete.org/MapComplete/MapComplete/issues"
target="_blank"
>
<Bug class="h-6 w-6" />
<Tr t={Translations.t.general.attribution.openIssueTracker} />
</a>

View file

@ -60,7 +60,9 @@
export let presetProperties: Tag[] = []
let presetPropertiesUnpacked = TagUtils.KVtoProperties(presetProperties)
export let snappedTo: UIEventSource<WayId | undefined> = new UIEventSource<WayId | undefined>(undefined)
export let snappedTo: UIEventSource<WayId | undefined> = new UIEventSource<WayId | undefined>(
undefined
)
const map: UIEventSource<MlMap> = new UIEventSource<MlMap>(undefined)
export let mapProperties: Partial<MapProperties> & { location } = {