diff --git a/LOTUS_FEATURES.md b/LOTUS_FEATURES.md index 250114466..5839cf6c1 100644 --- a/LOTUS_FEATURES.md +++ b/LOTUS_FEATURES.md @@ -722,7 +722,7 @@ Images and videos can be sent with a caption. The caption and media are sent as ### Location Sharing -`m.location` events render an inline map tile using the coordinates from the event content. +`m.location` events render an inline map tile using the coordinates from the event content. The renderer reads the top-level `geo_uri` and **falls back to the MSC3488 `org.matrix.msc3488.location`/`m.location` `uri`**, so locations from clients that send only the new shape still render (previously they showed as broken); an MSC3488 `description`, if present, is shown above the coordinates. Sharing your location (composer → location button) sends an **MSC3488-compliant** `m.location` event: the legacy `geo_uri` plus the `org.matrix.msc3488.location` (uri), `org.matrix.msc3488.asset` (`m.self`), and `org.matrix.msc3488.ts`/`m.ts` blocks, and a human-readable `body`. This makes Lotus-shared locations render as proper pins on Element and other clients instead of falling back to plain text. diff --git a/src/app/components/message/MsgTypeRenderers.tsx b/src/app/components/message/MsgTypeRenderers.tsx index 51df01293..83edcdd9d 100644 --- a/src/app/components/message/MsgTypeRenderers.tsx +++ b/src/app/components/message/MsgTypeRenderers.tsx @@ -514,7 +514,19 @@ type MLocationProps = { }; export function MLocation({ content }: MLocationProps) { const { t } = useTranslation(); - const geoUri = content.geo_uri; + // Prefer the legacy top-level geo_uri, but fall back to the MSC3488 extensible + // location block so events from clients that only send the new shape (uri under + // org.matrix.msc3488.location / m.location) still render instead of appearing + // broken. + const msc3488 = (content['org.matrix.msc3488.location'] ?? content['m.location']) as + | { uri?: string; description?: string } + | undefined; + const geoUri = + typeof content.geo_uri === 'string' + ? content.geo_uri + : typeof msc3488?.uri === 'string' + ? msc3488.uri + : undefined; if (typeof geoUri !== 'string') return ; const location = parseGeoUri(geoUri); if (!location) return ; @@ -522,6 +534,7 @@ export function MLocation({ content }: MLocationProps) { const lat = parseFloat(location.latitude); const lon = parseFloat(location.longitude); if (!isFinite(lat) || !isFinite(lon)) return ; + const description = typeof msc3488?.description === 'string' ? msc3488.description : undefined; const mapSrc = `https://www.openstreetmap.org/export/embed.html?bbox=${lon - 0.007},${ lat - 0.004 },${lon + 0.007},${lat + 0.004}&layer=mapnik&marker=${lat},${lon}`; @@ -542,6 +555,7 @@ export function MLocation({ content }: MLocationProps) { loading="lazy" sandbox="allow-scripts" /> + {description && {description}} {`${lat.toFixed(5)}, ${lon.toFixed(5)}`}