UI: update community index view to point to the selfhosted server

This commit is contained in:
Pieter Vander Vennet 2025-01-27 03:47:50 +01:00
parent 7f5b797b7d
commit 3c6606c90b
7 changed files with 33 additions and 368 deletions

View file

@ -59,6 +59,7 @@
"https://overpass.openstreetmap.ru/cgi/interpreter": "Broken as of 2024-09-05, might be a glitch" "https://overpass.openstreetmap.ru/cgi/interpreter": "Broken as of 2024-09-05, might be a glitch"
}, },
"country_coder_host": "https://countrycoder.mapcomplete.org", "country_coder_host": "https://countrycoder.mapcomplete.org",
"community_index_host": "https://data.mapcomplete.org/community-index/",
"nominatimEndpoint": "https://geocoding.geofabrik.de/b75350b1cfc34962ac49824fe5b582dc/", "nominatimEndpoint": "https://geocoding.geofabrik.de/b75350b1cfc34962ac49824fe5b582dc/",
"#photonEndpoint": "`api/` or `reverse/` will be appended by the code", "#photonEndpoint": "`api/` or `reverse/` will be appended by the code",
"photonEndpoint": "https://photon.komoot.io/", "photonEndpoint": "https://photon.komoot.io/",

View file

@ -1,5 +1,5 @@
import Script from "./Script" import Script from "./Script"
import { CommunityResource } from "../src/Logic/Web/CommunityIndex" import { CommunityResource } from "../src/Logic/Web/CommunityIndex"downlaodComm
import { Utils } from "../src/Utils" import { Utils } from "../src/Utils"
import { FeatureCollection, MultiPolygon, Polygon } from "geojson" import { FeatureCollection, MultiPolygon, Polygon } from "geojson"
import { existsSync, mkdirSync, writeFileSync } from "fs" import { existsSync, mkdirSync, writeFileSync } from "fs"
@ -41,6 +41,10 @@ class DownloadCommunityIndex extends Script {
private static stripResourcesObj(resources: Readonly<Record<string, Readonly<CommunityResource>>>) { private static stripResourcesObj(resources: Readonly<Record<string, Readonly<CommunityResource>>>) {
const stripped: Record<string, CommunityResource> = {} const stripped: Record<string, CommunityResource> = {}
for (const k in resources) { for (const k in resources) {
if(k === "twitter" || k === "facebook" || k === "x"){
// These channels are toxic nowadays - we simply omit them
continue
}
stripped[k] = DownloadCommunityIndex.stripResource(resources[k]) stripped[k] = DownloadCommunityIndex.stripResource(resources[k])
} }
return stripped return stripped

View file

@ -134,6 +134,8 @@ export default class Constants {
public static readonly mapillary_client_token_v4 = Constants.config.api_keys.mapillary_v4 public static readonly mapillary_client_token_v4 = Constants.config.api_keys.mapillary_v4
public static defaultOverpassUrls = Constants.config.default_overpass_urls public static defaultOverpassUrls = Constants.config.default_overpass_urls
public static countryCoderEndpoint: string = Constants.config.country_coder_host public static countryCoderEndpoint: string = Constants.config.country_coder_host
public static communityIndexHost: string = Constants.config.community_index_host
public static osmAuthConfig: AuthConfig = Constants.config.oauth_credentials public static osmAuthConfig: AuthConfig = Constants.config.oauth_credentials
public static nominatimEndpoint: string = Constants.config.nominatimEndpoint public static nominatimEndpoint: string = Constants.config.nominatimEndpoint
public static photonEndpoint: string = Constants.config.photonEndpoint public static photonEndpoint: string = Constants.config.photonEndpoint

View file

@ -9,7 +9,7 @@
export let fullscreen: boolean = false export let fullscreen: boolean = false
export let bodyPadding = "p-4 md:p-5 " export let bodyPadding = "p-4 md:p-5 "
export let shown: UIEventSource<boolean> export let shown: UIEventSource<boolean>
export let dismissable = false export let dismissable = true
/** /**
* Default: 50 * Default: 50
*/ */

View file

@ -2,7 +2,6 @@
import { Store, UIEventSource } from "../../Logic/UIEventSource" import { Store, UIEventSource } from "../../Logic/UIEventSource"
import { Tiles } from "../../Models/TileRange" import { Tiles } from "../../Models/TileRange"
import { Utils } from "../../Utils" import { Utils } from "../../Utils"
import global_community from "../../assets/community_index_global_resources.json"
import ContactLink from "./ContactLink.svelte" import ContactLink from "./ContactLink.svelte"
import { GeoOperations } from "../../Logic/GeoOperations" import { GeoOperations } from "../../Logic/GeoOperations"
import Translations from "../i18n/Translations" import Translations from "../i18n/Translations"
@ -10,11 +9,13 @@
import type { FeatureCollection, Polygon } from "geojson" import type { FeatureCollection, Polygon } from "geojson"
import type { CommunityResource } from "../../Logic/Web/CommunityIndex" import type { CommunityResource } from "../../Logic/Web/CommunityIndex"
import Tr from "../Base/Tr.svelte" 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 }> export let location: Store<{ lat: number; lon: number }>
const tileToFetch: Store<string> = location.mapD((l) => { const tileToFetch: Store<string> = location.mapD((l) => {
const t = Tiles.embedded_tile(l.lat, l.lon, 6) 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 t = Translations.t.communityIndex
const resources = new UIEventSource< const resources = new UIEventSource<
@ -32,17 +33,29 @@
resources.setData(data.features) resources.setData(data.features)
}) })
const filteredResources = resources.map( const filteredResources = resources.mapD(
(features) => (features) =>
features.filter((f) => GeoOperations.inside([location.data.lon, location.data.lat], f)), features.filter((f) => GeoOperations.inside([location.data.lon, location.data.lat], f)),
[location] [location]
) )
const globalResources: UIEventSource<Record<string, CommunityResource>> = UIEventSource.FromPromise(Utils.downloadJsonCached<Record<string, CommunityResource>>(
Constants.communityIndexHost + "/global.json", 24 * 60 * 60 * 1000
))
</script> </script>
<div> <div>
<Tr t={t.intro} /> <Tr t={t.intro} />
{#each $filteredResources as feature} {#if $filteredResources === undefined}
<ContactLink country={feature.properties} /> <Loading />
{/each} {:else}
<ContactLink country={{ resources: global_community, nameEn: "Global resources" }} /> {#each $filteredResources as feature}
<ContactLink country={feature.properties} />
{/each}
{/if}
{#if $globalResources === undefined}
<Loading />
{:else}
<ContactLink country={{ resources: $globalResources, nameEn: "Global resources" }} />
{/if}
</div> </div>

View file

@ -7,6 +7,7 @@
import { TypedTranslation } from "../i18n/Translation" import { TypedTranslation } from "../i18n/Translation"
import Tr from "../Base/Tr.svelte" import Tr from "../Base/Tr.svelte"
import type { CommunityResource } from "../../Logic/Web/CommunityIndex" import type { CommunityResource } from "../../Logic/Web/CommunityIndex"
import Constants from "../../Models/Constants"
const availableTranslationTyped: TypedTranslation<{ native: string }> = const availableTranslationTyped: TypedTranslation<{ native: string }> =
Translations.t.communityIndex.available Translations.t.communityIndex.available
@ -16,7 +17,6 @@
export let country: { resources: Record<string, CommunityResource>; nameEn: string } export let country: { resources: Record<string, CommunityResource>; nameEn: string }
let resources: CommunityResource[] = [] let resources: CommunityResource[] = []
$: resources = Array.from(Object.values(country?.resources ?? {})) $: resources = Array.from(Object.values(country?.resources ?? {}))
const language = Locale.language const language = Locale.language
</script> </script>
@ -28,16 +28,16 @@
<div class="link-underline my-4 flex items-center"> <div class="link-underline my-4 flex items-center">
<img <img
class="m-2 h-8 w-8" 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"> <div class="flex flex-col">
<a <a
href={resource.resolved.url} href={resource.resolved?.url}
target="_blank" target="_blank"
rel="noreferrer nofollow noopener" rel="noreferrer nofollow noopener"
class="font-bold" class="font-bold"
> >
{resource.resolved.name ?? resource.resolved.url} {resource.resolved?.name ?? resource.resolved?.url}
</a> </a>
{resource.resolved?.description} {resource.resolved?.description}
{#if resource.languageCodes?.indexOf($language) >= 0} {#if resource.languageCodes?.indexOf($language) >= 0}

View file

@ -1,355 +0,0 @@
{
"OSM-Discord": {
"id": "OSM-Discord",
"type": "discord",
"account": "openstreetmap",
"locationSet": {
"include": [
"001"
]
},
"languageCodes": [
"de",
"en",
"es",
"fr",
"it",
"pt-BR",
"ro",
"tr"
],
"order": 6,
"strings": {
"name": "OpenStreetMap World Discord"
},
"contacts": [
{
"name": "Austin Harrison",
"email": "jaustinharrison@gmail.com"
}
],
"resolved": {
"name": "OpenStreetMap World Discord",
"url": "https://discord.gg/openstreetmap",
"description": "Get in touch with other mappers on Discord",
"nameHTML": "<a target=\"_blank\" href=\"https://discord.gg/openstreetmap\">OpenStreetMap World Discord</a>",
"urlHTML": "<a target=\"_blank\" href=\"https://discord.gg/openstreetmap\">https://discord.gg/openstreetmap</a>",
"descriptionHTML": "Get in touch with other mappers on Discord"
}
},
"OSM-Discourse": {
"id": "OSM-Discourse",
"type": "discourse",
"locationSet": {
"include": [
"001"
]
},
"languageCodes": [
"de",
"en",
"es",
"nl",
"pl",
"pt-BR"
],
"order": 7,
"strings": {
"name": "OpenStreetMap Discourse",
"description": "A shared place for conversations about OpenStreetMap",
"url": "https://community.openstreetmap.org/"
},
"contacts": [
{
"name": "Grant Slater",
"email": "osmfuture@firefishy.com"
},
{
"name": "Rubén Martín",
"email": "nukeador@protonmail.com"
}
],
"resolved": {
"name": "OpenStreetMap Discourse",
"url": "https://community.openstreetmap.org/",
"description": "A shared place for conversations about OpenStreetMap",
"nameHTML": "<a target=\"_blank\" href=\"https://community.openstreetmap.org/\">OpenStreetMap Discourse</a>",
"urlHTML": "<a target=\"_blank\" href=\"https://community.openstreetmap.org/\">https://community.openstreetmap.org/</a>",
"descriptionHTML": "A shared place for conversations about OpenStreetMap"
}
},
"OSM-Facebook": {
"id": "OSM-Facebook",
"type": "facebook",
"account": "OpenStreetMap",
"locationSet": {
"include": [
"001"
]
},
"languageCodes": [
"en"
],
"order": 3,
"strings": {
"community": "OpenStreetMap",
"communityID": "openstreetmap",
"description": "Like us on Facebook for news and updates about OpenStreetMap."
},
"contacts": [
{
"name": "Harry Wood",
"email": "mail@harrywood.co.uk"
}
],
"resolved": {
"name": "OpenStreetMap on Facebook",
"url": "https://www.facebook.com/OpenStreetMap",
"description": "Like us on Facebook for news and updates about OpenStreetMap.",
"nameHTML": "<a target=\"_blank\" href=\"https://www.facebook.com/OpenStreetMap\">OpenStreetMap on Facebook</a>",
"urlHTML": "<a target=\"_blank\" href=\"https://www.facebook.com/OpenStreetMap\">https://www.facebook.com/OpenStreetMap</a>",
"descriptionHTML": "Like us on Facebook for news and updates about OpenStreetMap."
}
},
"OSM-help": {
"id": "OSM-help",
"type": "forum",
"locationSet": {
"include": [
"001"
]
},
"languageCodes": [
"en"
],
"order": -2,
"strings": {
"name": "OpenStreetMap Help",
"description": "Ask a question and get answers on OSM's community-driven question and answer site.",
"extendedDescription": "{url} is for everyone who needs help with OpenStreetMap. Whether you are a beginner mapper or have a technical question, we're here to help!",
"url": "https://help.openstreetmap.org/"
},
"contacts": [
{
"name": "OSMF Operations",
"email": "operations@osmfoundation.org"
}
],
"resolved": {
"name": "OpenStreetMap Help",
"url": "https://help.openstreetmap.org/",
"description": "Ask a question and get answers on OSM's community-driven question and answer site.",
"extendedDescription": "https://help.openstreetmap.org/ is for everyone who needs help with OpenStreetMap. Whether you are a beginner mapper or have a technical question, we're here to help!",
"nameHTML": "<a target=\"_blank\" href=\"https://help.openstreetmap.org/\">OpenStreetMap Help</a>",
"urlHTML": "<a target=\"_blank\" href=\"https://help.openstreetmap.org/\">https://help.openstreetmap.org/</a>",
"descriptionHTML": "Ask a question and get answers on OSM's community-driven question and answer site.",
"extendedDescriptionHTML": "<a target=\"_blank\" href=\"https://help.openstreetmap.org/\">https://help.openstreetmap.org/</a> is for everyone who needs help with OpenStreetMap. Whether you are a beginner mapper or have a technical question, we're here to help!"
}
},
"OSM-IRC": {
"id": "OSM-IRC",
"type": "irc",
"account": "osm",
"locationSet": {
"include": [
"001"
]
},
"languageCodes": [
"en"
],
"order": -4,
"strings": {
"community": "OpenStreetMap",
"communityID": "openstreetmap"
},
"contacts": [
{
"name": "Harry Wood",
"email": "mail@harrywood.co.uk"
}
],
"resolved": {
"name": "OpenStreetMap on IRC",
"url": "https://webchat.oftc.net/?channels=osm",
"description": "Join #osm on irc.oftc.net (port 6667)",
"nameHTML": "<a target=\"_blank\" href=\"https://webchat.oftc.net/?channels=osm\">OpenStreetMap on IRC</a>",
"urlHTML": "<a target=\"_blank\" href=\"https://webchat.oftc.net/?channels=osm\">https://webchat.oftc.net/?channels=osm</a>",
"descriptionHTML": "Join #osm on irc.oftc.net (port 6667)"
}
},
"OSM-Mastodon": {
"id": "OSM-Mastodon",
"type": "mastodon",
"account": "openstreetmap",
"locationSet": {
"include": [
"001"
]
},
"languageCodes": [
"en"
],
"order": 3,
"strings": {
"community": "OpenStreetMap",
"communityID": "openstreetmap",
"url": "https://en.osm.town/@openstreetmap"
},
"contacts": [
{
"name": "Harry Wood",
"email": "mail@harrywood.co.uk"
}
],
"resolved": {
"name": "OpenStreetMap Mastodon Account",
"url": "https://en.osm.town/@openstreetmap",
"description": "The official Mastodon account for OpenStreetMap",
"nameHTML": "<a target=\"_blank\" href=\"https://en.osm.town/@openstreetmap\">OpenStreetMap Mastodon Account</a>",
"urlHTML": "<a target=\"_blank\" href=\"https://en.osm.town/@openstreetmap\">https://en.osm.town/@openstreetmap</a>",
"descriptionHTML": "The official Mastodon account for OpenStreetMap"
}
},
"OSM-Reddit": {
"id": "OSM-Reddit",
"type": "reddit",
"account": "openstreetmap",
"locationSet": {
"include": [
"001"
]
},
"languageCodes": [
"en"
],
"order": 2,
"strings": {
"community": "OpenStreetMap",
"communityID": "openstreetmap",
"description": "/r/{account} is a great place to learn more about OpenStreetMap. Ask us anything!"
},
"contacts": [
{
"name": "Serge Wroclawski",
"email": "emacsen@gmail.com"
}
],
"resolved": {
"name": "OpenStreetMap on Reddit",
"url": "https://www.reddit.com/r/openstreetmap",
"description": "/r/openstreetmap is a great place to learn more about OpenStreetMap. Ask us anything!",
"nameHTML": "<a target=\"_blank\" href=\"https://www.reddit.com/r/openstreetmap\">OpenStreetMap on Reddit</a>",
"urlHTML": "<a target=\"_blank\" href=\"https://www.reddit.com/r/openstreetmap\">https://www.reddit.com/r/openstreetmap</a>",
"descriptionHTML": "<a target=\"_blank\" href=\"https://www.reddit.com/r/openstreetmap\">/r/openstreetmap</a> is a great place to learn more about OpenStreetMap. Ask us anything!"
}
},
"OSM-Telegram": {
"id": "OSM-Telegram",
"type": "telegram",
"account": "OpenStreetMapOrg",
"locationSet": {
"include": [
"001"
]
},
"languageCodes": [
"en"
],
"order": 5,
"strings": {
"community": "OpenStreetMap",
"communityID": "openstreetmap",
"description": "Join the OpenStreetMap Telegram global supergroup at {url}"
},
"contacts": [
{
"name": "Max N",
"email": "abonnements@revolwear.com"
}
],
"resolved": {
"name": "OpenStreetMap Telegram",
"url": "https://t.me/OpenStreetMapOrg",
"description": "Join the OpenStreetMap Telegram global supergroup at https://t.me/OpenStreetMapOrg",
"nameHTML": "<a target=\"_blank\" href=\"https://t.me/OpenStreetMapOrg\">OpenStreetMap Telegram</a>",
"urlHTML": "<a target=\"_blank\" href=\"https://t.me/OpenStreetMapOrg\">https://t.me/OpenStreetMapOrg</a>",
"descriptionHTML": "Join the OpenStreetMap Telegram global supergroup at <a target=\"_blank\" href=\"https://t.me/OpenStreetMapOrg\">https://t.me/OpenStreetMapOrg</a>"
}
},
"OSM-Twitter": {
"id": "OSM-Twitter",
"type": "twitter",
"account": "openstreetmap",
"locationSet": {
"include": [
"001"
]
},
"languageCodes": [
"en"
],
"order": 4,
"strings": {
"community": "OpenStreetMap",
"communityID": "openstreetmap"
},
"contacts": [
{
"name": "Harry Wood",
"email": "mail@harrywood.co.uk"
}
],
"resolved": {
"name": "OpenStreetMap on Twitter",
"url": "https://twitter.com/openstreetmap",
"description": "Follow us on Twitter",
"nameHTML": "<a target=\"_blank\" href=\"https://twitter.com/openstreetmap\">OpenStreetMap on Twitter</a>",
"urlHTML": "<a target=\"_blank\" href=\"https://twitter.com/openstreetmap\">https://twitter.com/openstreetmap</a>",
"descriptionHTML": "Follow us on Twitter"
}
},
"OSMF": {
"id": "OSMF",
"type": "osm-lc",
"locationSet": {
"include": [
"001"
]
},
"languageCodes": [
"en",
"fr",
"it",
"ja",
"nl",
"ru"
],
"order": 10,
"strings": {
"name": "OpenStreetMap Foundation",
"description": "OSMF is a UK-based not-for-profit that supports the OpenStreetMap Project",
"extendedDescription": "OSMF supports the OpenStreetMap project by fundraising, maintaining the servers which power OSM, organizing the annual State of the Map conference, and coordinating the volunteers who keep OSM running. You can show your support and have a voice in the direction of OpenStreetMap by joining as an OSMF member here: {signupUrl}",
"signupUrl": "https://join.osmfoundation.org/",
"url": "https://wiki.osmfoundation.org/wiki/Main_Page"
},
"contacts": [
{
"name": "OSMF Board",
"email": "board@osmfoundation.org"
}
],
"resolved": {
"name": "OpenStreetMap Foundation",
"url": "https://wiki.osmfoundation.org/wiki/Main_Page",
"signupUrl": "https://join.osmfoundation.org/",
"description": "OSMF is a UK-based not-for-profit that supports the OpenStreetMap Project",
"extendedDescription": "OSMF supports the OpenStreetMap project by fundraising, maintaining the servers which power OSM, organizing the annual State of the Map conference, and coordinating the volunteers who keep OSM running. You can show your support and have a voice in the direction of OpenStreetMap by joining as an OSMF member here: https://join.osmfoundation.org/",
"nameHTML": "<a target=\"_blank\" href=\"https://wiki.osmfoundation.org/wiki/Main_Page\">OpenStreetMap Foundation</a>",
"urlHTML": "<a target=\"_blank\" href=\"https://wiki.osmfoundation.org/wiki/Main_Page\">https://wiki.osmfoundation.org/wiki/Main_Page</a>",
"signupUrlHTML": "<a target=\"_blank\" href=\"https://join.osmfoundation.org/\">https://join.osmfoundation.org/</a>",
"descriptionHTML": "OSMF is a UK-based not-for-profit that supports the OpenStreetMap Project",
"extendedDescriptionHTML": "OSMF supports the OpenStreetMap project by fundraising, maintaining the servers which power OSM, organizing the annual State of the Map conference, and coordinating the volunteers who keep OSM running. You can show your support and have a voice in the direction of OpenStreetMap by joining as an OSMF member here: <a target=\"_blank\" href=\"https://join.osmfoundation.org/\">https://join.osmfoundation.org/</a>"
}
}
}