Allow opening a map view in OpenStreetMap (#7428)

This commit is contained in:
Andy Balaam 2021-12-21 15:48:20 +00:00 committed by GitHub
parent 38634f86d1
commit a239c456e3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 143 additions and 2 deletions

View file

@ -46,6 +46,7 @@ import { ComposerInsertPayload } from "../../../dispatcher/payloads/ComposerInse
import { WidgetLayoutStore } from '../../../stores/widgets/WidgetLayoutStore';
import EndPollDialog from '../dialogs/EndPollDialog';
import { isPollEnded } from '../messages/MPollBody';
import { createMapSiteLink } from "../messages/MLocationBody";
export function canCancel(eventStatus: EventStatus): boolean {
return eventStatus === EventStatus.QUEUED || eventStatus === EventStatus.NOT_SENT;
@ -133,9 +134,13 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
return content.pinned && Array.isArray(content.pinned) && content.pinned.includes(this.props.mxEvent.getId());
}
private canOpenInMapSite(mxEvent: MatrixEvent): boolean {
return isLocationEvent(mxEvent);
}
private canEndPoll(mxEvent: MatrixEvent): boolean {
return (
mxEvent.getType() === POLL_START_EVENT_TYPE.name &&
POLL_START_EVENT_TYPE.matches(mxEvent.getType()) &&
this.state.canRedact &&
!isPollEnded(mxEvent, MatrixClientPeg.get(), this.props.getRelationsForEvent)
);
@ -278,6 +283,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
const eventStatus = mxEvent.status;
const unsentReactionsCount = this.getUnsentReactions().length;
let openInMapSiteButton: JSX.Element;
let endPollButton: JSX.Element;
let resendReactionsButton: JSX.Element;
let redactButton: JSX.Element;
@ -313,6 +319,25 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
);
}
if (this.canOpenInMapSite(mxEvent)) {
const mapSiteLink = createMapSiteLink(mxEvent);
openInMapSiteButton = (
<IconizedContextMenuOption
iconClassName="mx_MessageContextMenu_iconOpenInMapSite"
onClick={null}
label={_t('Open in OpenStreetMap')}
element="a"
{
...{
href: mapSiteLink,
target: "_blank",
rel: "noreferrer noopener",
}
}
/>
);
}
if (isContentActionable(mxEvent)) {
if (canForward(mxEvent)) {
forwardButton = (
@ -459,6 +484,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
label={_t("View in room")}
onClick={this.viewInRoom}
/> }
{ openInMapSiteButton }
{ endPollButton }
{ quoteButton }
{ forwardButton }

View file

@ -90,3 +90,4 @@ export function textForLocation(
}
}
export default LocationButton;

View file

@ -18,6 +18,7 @@ import React from 'react';
import maplibregl from 'maplibre-gl';
import { logger } from "matrix-js-sdk/src/logger";
import { LOCATION_EVENT_TYPE } from 'matrix-js-sdk/src/@types/location';
import { MatrixEvent } from 'matrix-js-sdk/src/models/event';
import SdkConfig from '../../../SdkConfig';
import { replaceableComponent } from "../../../utils/replaceableComponent";
@ -147,3 +148,29 @@ export function parseGeoUri(uri: string): GeolocationCoordinates {
speed: undefined,
};
}
function makeLink(coords: GeolocationCoordinates): string {
return (
"https://www.openstreetmap.org/" +
`?mlat=${coords.latitude}` +
`&mlon=${coords.longitude}` +
`#map=16/${coords.latitude}/${coords.longitude}`
);
}
export function createMapSiteLink(event: MatrixEvent): string {
const content: Object = event.getContent();
const mLocation = content[LOCATION_EVENT_TYPE.name];
if (mLocation !== undefined) {
const uri = mLocation["uri"];
if (uri !== undefined) {
return makeLink(parseGeoUri(uri));
}
} else {
const geoUri = content["geo_uri"];
if (geoUri) {
return makeLink(parseGeoUri(geoUri));
}
}
return null;
}

View file

@ -32,3 +32,5 @@ export const CollapsibleButton = ({ narrowMode, title, ...props }: ICollapsibleB
label={narrowMode ? title : undefined}
/>;
};
export default CollapsibleButton;