Proxy the member map's CARTO tiles through dufflepud (#676)

This commit is contained in:
Coracle-Bot 2026-09-29 16:51:24 +00:00 committed by hodlbod
parent 64767dc5a5
commit c8edff5063
6 changed files with 14 additions and 27 deletions

2
.env
View file

@ -22,8 +22,6 @@ VITE_DEFAULT_SEARCH_RELAYS=relay.ditto.pub,antiprimal.net,relay.vertexlab.io
VITE_DEFAULT_MESSAGING_RELAYS=auth.nostr1.com,relay.keychat.io,relay.ditto.pub
VITE_SIGNER_RELAYS=ephemeral.snowflare.cc,bucket.coracle.social
VITE_THUMBNAIL_URL=https://vthumbs.coracle.social
VITE_CARTO_BASEMAP_KEY=cb1_42g1_1_7234813dd26909cd44b1dbe8
VITE_CARTO_BASEMAP_KEY_LOCALHOST=cb1_42g1_3_bb09b0b53486b8f945a77a82
VITE_GLITCHTIP_API_KEY=
GLITCHTIP_AUTH_TOKEN=
VITE_HOSTING_BACKEND_URL=https://api.hosting.coracle.social

View file

@ -56,7 +56,6 @@ jobs:
VITE_PLATFORM_URL: https://pr-${{ github.event.number }}.preview.flowboat.lol
VITE_PLATFORM_NAME: "Flotilla PR #${{ github.event.number }}"
VITE_PLATFORM_DESCRIPTION: "Preview build of coracle/flotilla PR #${{ github.event.number }}. Not the real Flotilla."
VITE_CARTO_BASEMAP_KEY: cb1_42g1_2_bc3246a5d40392210ca7ab64
run: |
export VITE_BUILD_HASH="${HEAD_SHA:0:8}"
pnpm run build

View file

@ -61,8 +61,6 @@ Create an `.env.local` file to override any of the values in `.env`:
- `VITE_PUSH_BRIDGE` - WebSocket URL of the push notification relay bridge
- `VITE_POMADE_SIGNERS` - A comma-separated list of Pomade signer server URLs (3+ required to enable email signup)
- `VITE_THUMBNAIL_URL` - URL of the image thumbnail service
- `VITE_CARTO_BASEMAP_KEY` - A CARTO Basemaps key for the member map's tiles, free from https://carto.com/basemaps/apikey/. Without one the tiles carry an "API key required" watermark.
- `VITE_CARTO_BASEMAP_KEY_LOCALHOST` - The CARTO key for the native apps and the dev server, which both serve from `localhost`. CARTO authorizes a key against a list of domains and refuses `localhost` on one that also names a real domain, so this is a second key.
These values **won't** be used for a built version. Instead, env variables should be provided to `scripts/build/app.sh` directly or to the built container.

View file

@ -138,7 +138,7 @@ createCapacitorElectronApp({
"default-src 'self'",
"script-src 'self' 'unsafe-inline' 'unsafe-eval' https://plausible.coracle.social",
"style-src 'self' 'unsafe-inline'",
"img-src 'self' data: blob: https://basemaps.cartocdn.com",
"img-src 'self' data: blob: https://dufflepud.coracle.social",
"font-src 'self' data:",
"media-src 'self' blob:",
"connect-src 'self' https: wss: ws: http:",

View file

@ -3,6 +3,7 @@
import MenuButton from "@lib/components/MenuButton.svelte"
import Profile from "@app/components/Profile.svelte"
import ProfileAbout from "@app/components/ProfileAbout.svelte"
import ProfileLocation from "@app/components/ProfileLocation.svelte"
import ProfileDetail from "@app/components/ProfileDetail.svelte"
import SpaceMemberMenu from "@app/components/SpaceMemberMenu.svelte"
import RoleBadge from "@app/components/RoleBadge.svelte"
@ -44,6 +45,7 @@
<div class="line-clamp-1 text-sm opacity-70">
<ProfileAbout {pubkey} {url} singleLine />
</div>
<ProfileLocation {pubkey} {url} />
</div>
{#if $permissions.memberMenu}
<div class="pointer-events-auto shrink-0">

View file

@ -6,6 +6,7 @@
import type {Maybe} from "@welshman/lib"
import ProfileCircle from "@app/components/ProfileCircle.svelte"
import ProfileDetail from "@app/components/ProfileDetail.svelte"
import {dufflepud} from "@app/env"
import {pushModal} from "@app/modal"
import {activeTheme} from "@app/theme"
import type {MemberPin} from "@app/social"
@ -19,12 +20,6 @@
const basemap = $derived($activeTheme === "dark" ? "dark_all" : "light_all")
// CARTO authorizes a key per referer, and the native apps and the dev server both serve from localhost.
const basemapKey =
location.hostname === "localhost"
? import.meta.env.VITE_CARTO_BASEMAP_KEY_LOCALHOST
: import.meta.env.VITE_CARTO_BASEMAP_KEY
const openProfile = (pubkey: string) => pushModal(ProfileDetail, {pubkey, url})
let element: HTMLElement
@ -49,14 +44,11 @@
if (leaflet && map) {
tile = leaflet
.tileLayer(
`https://basemaps.cartocdn.com/rastertiles/${basemap}/{z}/{x}/{y}.png?key=${basemapKey}`,
{
maxZoom: 12,
attribution:
'&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, &copy; <a href="https://carto.com/attribution/">CARTO</a>',
},
)
.tileLayer(dufflepud(`basemap/${basemap}/{z}/{x}/{y}.png`), {
maxZoom: 12,
attribution:
'&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, &copy; <a href="https://carto.com/attribution/">CARTO</a>',
})
.addTo(map)
}
@ -71,15 +63,13 @@
for (const pin of pins) {
const target = document.createElement("div")
target.className =
"flex size-11 items-center justify-center rounded-full border border-line bg-surface shadow-lg"
avatars.push(
mount(ProfileCircle, {
target,
props: {
pubkey: pin.pubkey,
url,
size: 10,
class: "bg-surface ring-2 ring-surface shadow-lg",
},
props: {pubkey: pin.pubkey, url, size: 9},
}),
)
@ -88,7 +78,7 @@
.marker([pin.latitude, pin.longitude], {
title: pin.display,
// An empty className replaces the white box leaflet gives a div icon.
icon: leaflet.divIcon({html: target, className: "", iconSize: [40, 40]}),
icon: leaflet.divIcon({html: target, className: "", iconSize: [48, 48]}),
})
.on("click", () => openProfile(pin.pubkey))
.addTo(map),