forked from MapComplete/MapComplete
Merge develop
This commit is contained in:
commit
3fe1f39c46
457 changed files with 6866 additions and 218533 deletions
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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 } = {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue