Simple static location sharing (#7135)
Adds maplibre as a dependency, and behind a labs flag, lets users send and receive [MSC3488](https://github.com/matrix-org/matrix-doc/blob/matthew/location/proposals/3488-location.md) style location shares - with backwards compatibility with old school `m.location` `msgtype` location shares too. For this to work, you have to define a valid maptile server and API in your config.json's `map_style_url`.pull/21833/head
parent
eb05044bc4
commit
1262021417
|
@ -57,6 +57,7 @@
|
|||
"@babel/runtime": "^7.12.5",
|
||||
"@sentry/browser": "^6.11.0",
|
||||
"@sentry/tracing": "^6.11.0",
|
||||
"@types/geojson": "^7946.0.8",
|
||||
"await-lock": "^2.1.0",
|
||||
"blurhash": "^1.1.3",
|
||||
"browser-encrypt-attachment": "^0.3.0",
|
||||
|
@ -83,6 +84,7 @@
|
|||
"katex": "^0.12.0",
|
||||
"linkifyjs": "^2.1.9",
|
||||
"lodash": "^4.17.20",
|
||||
"maplibre-gl": "^1.15.2",
|
||||
"matrix-js-sdk": "github:matrix-org/matrix-js-sdk#develop",
|
||||
"matrix-widget-api": "^0.1.0-beta.18",
|
||||
"minimist": "^1.2.5",
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
/*
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
Copyright 2017 Vector Creations Ltd
|
||||
Copyright 2017 New Vector Ltd
|
||||
Copyright 2017 - 2019 New Vector Ltd
|
||||
Copyright 2019 - 2021 The Matrix.org Foundation C.I.C
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -19,6 +20,7 @@ limitations under the License.
|
|||
@import "./_font-sizes.scss";
|
||||
@import "./_font-weights.scss";
|
||||
@import "./_animations.scss";
|
||||
@import url("maplibre-gl/dist/maplibre-gl.css");
|
||||
|
||||
$hover-transition: 0.08s cubic-bezier(.46, .03, .52, .96); // quadratic
|
||||
|
||||
|
|
|
@ -173,6 +173,7 @@
|
|||
@import "./views/groups/_GroupPublicityToggle.scss";
|
||||
@import "./views/groups/_GroupRoomList.scss";
|
||||
@import "./views/groups/_GroupUserSettings.scss";
|
||||
@import "./views/location/_LocationPicker.scss";
|
||||
@import "./views/messages/_CallEvent.scss";
|
||||
@import "./views/messages/_CreateEvent.scss";
|
||||
@import "./views/messages/_DateSeparator.scss";
|
||||
|
@ -182,6 +183,7 @@
|
|||
@import "./views/messages/_MImageBody.scss";
|
||||
@import "./views/messages/_MImageReplyBody.scss";
|
||||
@import "./views/messages/_MJitsiWidgetEvent.scss";
|
||||
@import "./views/messages/_MLocationBody.scss";
|
||||
@import "./views/messages/_MNoticeBody.scss";
|
||||
@import "./views/messages/_MPollBody.scss";
|
||||
@import "./views/messages/_MStickerBody.scss";
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
Copyright 2021 The Matrix.org Foundation C.I.C
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
.mx_LocationPicker {
|
||||
// placeholder sizing to be replaced once there's a proper design
|
||||
width: 450px;
|
||||
height: 500px;
|
||||
|
||||
border-radius: 4px;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
#mx_LocationPicker_map {
|
||||
height: 324px;
|
||||
border-radius: 8px 8px 0px 0px;
|
||||
}
|
||||
|
||||
.mx_LocationPicker_footer {
|
||||
margin: 24px;
|
||||
|
||||
.mx_Dropdown_menu {
|
||||
max-height: 140px;
|
||||
}
|
||||
}
|
||||
|
||||
.mx_LocationPicker_error {
|
||||
color: red;
|
||||
margin: auto;
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
Copyright 2021 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
.mx_MLocationBody_map {
|
||||
width: 450px;
|
||||
height: 300px;
|
||||
|
||||
border-radius: $timeline-image-border-radius;
|
||||
}
|
|
@ -256,6 +256,10 @@ limitations under the License.
|
|||
mask-image: url('$(res)/img/element-icons/room/composer/emoji.svg');
|
||||
}
|
||||
|
||||
.mx_MessageComposer_location::before {
|
||||
mask-image: url('$(res)/img/element-icons/room/composer/location.svg');
|
||||
}
|
||||
|
||||
.mx_MessageComposer_stickers::before {
|
||||
mask-image: url('$(res)/img/element-icons/room/composer/sticker.svg');
|
||||
}
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M12 2C8.13 2 5 5.13 5 9C5 13.17 9.42 18.92 11.24 21.11C11.64 21.59 12.37 21.59 12.77 21.11C14.58 18.92 19 13.17 19 9C19 5.13 15.87 2 12 2ZM12 11.5C10.62 11.5 9.5 10.38 9.5 9C9.5 7.62 10.62 6.5 12 6.5C13.38 6.5 14.5 7.62 14.5 9C14.5 10.38 13.38 11.5 12 11.5Z" fill="#0DBD8B"/>
|
||||
</svg>
|
After Width: | Height: | Size: 388 B |
|
@ -0,0 +1,200 @@
|
|||
/*
|
||||
Copyright 2021 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import maplibregl from 'maplibre-gl';
|
||||
|
||||
import SdkConfig from '../../../SdkConfig';
|
||||
import Field from "../elements/Field";
|
||||
import DialogButtons from "../elements/DialogButtons";
|
||||
import Dropdown from "../elements/Dropdown";
|
||||
import LocationShareType from "./LocationShareType";
|
||||
|
||||
import { _t } from '../../../languageHandler';
|
||||
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
|
||||
interface IDropdownProps {
|
||||
value: LocationShareType;
|
||||
label: string;
|
||||
width?: number;
|
||||
onChange(type: LocationShareType): void;
|
||||
}
|
||||
|
||||
const LocationShareTypeDropdown = ({
|
||||
value,
|
||||
label,
|
||||
width,
|
||||
onChange,
|
||||
}: IDropdownProps) => {
|
||||
const options = [
|
||||
// <div key={LocationShareType.Custom}>{ _t("Share custom location") }</div>,
|
||||
<div key={LocationShareType.OnceOff}>{ _t("Share my current location as a once off") }</div>,
|
||||
// <div key={LocationShareType.OneMin}>{ _t("Share my current location for one minute") }</div>,
|
||||
// <div key={LocationShareType.FiveMins}>{ _t("Share my current location for five minutes") }</div>,
|
||||
// <div key={LocationShareType.ThirtyMins}>{ _t("Share my current location for thirty minutes") }</div>,
|
||||
// <div key={LocationShareType.OneHour}>{ _t("Share my current location for one hour") }</div>,
|
||||
// <div key={LocationShareType.ThreeHours}>{ _t("Share my current location for three hours") }</div>,
|
||||
// <div key={LocationShareType.SixHours}>{ _t("Share my current location for six hours") }</div>,
|
||||
// <div key={LocationShareType.OneDay}>{ _t("Share my current location for one day") }</div>,
|
||||
// <div key={LocationShareType.Forever}>{ _t("Share my current location until I disable it") }</div>,
|
||||
];
|
||||
|
||||
return <Dropdown
|
||||
id="mx_LocationShareTypeDropdown"
|
||||
className="mx_LocationShareTypeDropdown"
|
||||
onOptionChange={(key: string)=>{ onChange(LocationShareType[LocationShareType[parseInt(key)]]); }}
|
||||
menuWidth={width}
|
||||
label={label}
|
||||
value={value.toString()}
|
||||
>
|
||||
{ options }
|
||||
</Dropdown>;
|
||||
};
|
||||
|
||||
interface IProps {
|
||||
onChoose(uri: string, ts: number, type: LocationShareType, description: string): boolean;
|
||||
onFinished();
|
||||
}
|
||||
|
||||
interface IState {
|
||||
description: string;
|
||||
type: LocationShareType;
|
||||
position?: GeolocationPosition;
|
||||
manual: boolean;
|
||||
error: Error;
|
||||
}
|
||||
|
||||
@replaceableComponent("views.location.LocationPicker")
|
||||
class LocationPicker extends React.Component<IProps, IState> {
|
||||
private map: maplibregl.Map;
|
||||
private geolocate: maplibregl.GeolocateControl;
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
description: _t("My location"),
|
||||
type: LocationShareType.OnceOff,
|
||||
position: undefined,
|
||||
manual: false,
|
||||
error: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const config = SdkConfig.get();
|
||||
this.map = new maplibregl.Map({
|
||||
container: 'mx_LocationPicker_map',
|
||||
style: config.map_style_url,
|
||||
center: [0, 0],
|
||||
zoom: 1,
|
||||
});
|
||||
|
||||
// Add geolocate control to the map.
|
||||
this.geolocate = new maplibregl.GeolocateControl({
|
||||
positionOptions: {
|
||||
enableHighAccuracy: true,
|
||||
},
|
||||
trackUserLocation: true,
|
||||
});
|
||||
this.map.addControl(this.geolocate);
|
||||
|
||||
this.map.on('error', (e)=>{
|
||||
logger.error("Failed to load map: check map_style_url in config.json has a valid URL and API key", e.error);
|
||||
this.setState({ error: e.error });
|
||||
});
|
||||
|
||||
this.map.on('load', ()=>{
|
||||
this.geolocate.trigger();
|
||||
});
|
||||
|
||||
this.geolocate.on('geolocate', this.onGeolocate);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.geolocate.off('geolocate', this.onGeolocate);
|
||||
}
|
||||
|
||||
private onGeolocate = (position) => {
|
||||
this.setState({ position });
|
||||
};
|
||||
|
||||
private onDescriptionChange = (ev: React.ChangeEvent<HTMLInputElement>) => {
|
||||
this.setState({ description: ev.target.value });
|
||||
};
|
||||
|
||||
private getGeoUri = (position) => {
|
||||
return (`geo:${ position.coords.latitude },` +
|
||||
position.coords.longitude +
|
||||
( position.coords.altitude != null ?
|
||||
`,${ position.coords.altitude }` : '' ) +
|
||||
`;u=${ position.coords.accuracy }`);
|
||||
};
|
||||
|
||||
private onOk = () => {
|
||||
this.props.onChoose(
|
||||
this.state.position ? this.getGeoUri(this.state.position) : undefined,
|
||||
this.state.position ? this.state.position.timestamp : undefined,
|
||||
this.state.type,
|
||||
this.state.description,
|
||||
);
|
||||
this.props.onFinished();
|
||||
};
|
||||
|
||||
private onTypeChange= (type: LocationShareType) => {
|
||||
this.setState({ type });
|
||||
};
|
||||
|
||||
render() {
|
||||
const error = this.state.error ?
|
||||
<div className="mx_LocationPicker_error">
|
||||
{ _t("Failed to load map") }
|
||||
</div> : null;
|
||||
|
||||
return (
|
||||
<div className="mx_LocationPicker">
|
||||
<div id="mx_LocationPicker_map" />
|
||||
{ error }
|
||||
<div className="mx_LocationPicker_footer">
|
||||
<form onSubmit={this.onOk}>
|
||||
<LocationShareTypeDropdown
|
||||
value={this.state.type}
|
||||
label={_t("Type of location share")}
|
||||
onChange={this.onTypeChange}
|
||||
width={400}
|
||||
/>
|
||||
|
||||
<Field
|
||||
label={_t('Description')}
|
||||
onChange={this.onDescriptionChange}
|
||||
value={this.state.description}
|
||||
width={400}
|
||||
className="mx_LocationPicker_description"
|
||||
/>
|
||||
|
||||
<DialogButtons primaryButton={_t('Share')}
|
||||
onPrimaryButtonClick={this.onOk}
|
||||
onCancel={this.props.onFinished}
|
||||
disabled={!this.state.position} />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default LocationPicker;
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
Copyright 2021 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
enum LocationShareType {
|
||||
Custom = -1,
|
||||
OnceOff = 0,
|
||||
OneMine = 60,
|
||||
FiveMins = 5 * 60,
|
||||
ThirtyMins = 30 * 60,
|
||||
OneHour = 60 * 60,
|
||||
ThreeHours = 3 * 60 * 60,
|
||||
SixHours = 6 * 60 * 60,
|
||||
OneDay = 24 * 60 * 60,
|
||||
Forever = Number.MAX_SAFE_INTEGER,
|
||||
}
|
||||
|
||||
export default LocationShareType;
|
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
Copyright 2021 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import maplibregl from 'maplibre-gl';
|
||||
import SdkConfig from '../../../SdkConfig';
|
||||
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
||||
import { IBodyProps } from "./IBodyProps";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { _t } from '../../../languageHandler';
|
||||
|
||||
interface IState {
|
||||
error: Error;
|
||||
}
|
||||
|
||||
@replaceableComponent("views.messages.MLocationBody")
|
||||
export default class MLocationBody extends React.Component<IBodyProps, IState> {
|
||||
private map: maplibregl.Map;
|
||||
private coords: GeolocationCoordinates;
|
||||
private description: string;
|
||||
|
||||
constructor(props: IBodyProps) {
|
||||
super(props);
|
||||
|
||||
// unfortunately we're stuck supporting legacy `content.geo_uri`
|
||||
// events until the end of days, or until we figure out mutable
|
||||
// events - so folks can read their old chat history correctly.
|
||||
// https://github.com/matrix-org/matrix-doc/issues/3516
|
||||
const content = this.props.mxEvent.getContent();
|
||||
const uri = content['org.matrix.msc3488.location'] ?
|
||||
content['org.matrix.msc3488.location'].uri :
|
||||
content['geo_uri'];
|
||||
|
||||
this.coords = this.parseGeoUri(uri);
|
||||
this.state = {
|
||||
error: undefined,
|
||||
};
|
||||
|
||||
this.description =
|
||||
content['org.matrix.msc3488.location']?.description ?? content['body'];
|
||||
}
|
||||
|
||||
private parseGeoUri = (uri: string): GeolocationCoordinates => {
|
||||
const m = uri.match(/^\s*geo:(.*?)\s*$/);
|
||||
if (!m) return;
|
||||
const parts = m[1].split(';');
|
||||
const coords = parts[0].split(',');
|
||||
let uncertainty: number;
|
||||
for (const param of parts.slice(1)) {
|
||||
const m = param.match(/u=(.*)/);
|
||||
if (m) uncertainty = parseFloat(m[1]);
|
||||
}
|
||||
return {
|
||||
latitude: parseFloat(coords[0]),
|
||||
longitude: parseFloat(coords[1]),
|
||||
altitude: parseFloat(coords[2]),
|
||||
accuracy: uncertainty,
|
||||
altitudeAccuracy: undefined,
|
||||
heading: undefined,
|
||||
speed: undefined,
|
||||
};
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
const config = SdkConfig.get();
|
||||
this.map = new maplibregl.Map({
|
||||
container: this.getBodyId(),
|
||||
style: config.map_style_url,
|
||||
center: [this.coords.longitude, this.coords.latitude],
|
||||
zoom: 13,
|
||||
});
|
||||
|
||||
new maplibregl.Marker()
|
||||
.setLngLat([this.coords.longitude, this.coords.latitude])
|
||||
.addTo(this.map);
|
||||
|
||||
this.map.on('error', (e)=>{
|
||||
logger.error("Failed to load map: check map_style_url in config.json has a valid URL and API key", e.error);
|
||||
this.setState({ error: e.error });
|
||||
});
|
||||
}
|
||||
|
||||
private getBodyId = () => {
|
||||
return `mx_MLocationBody_${this.props.mxEvent.getId()}`;
|
||||
};
|
||||
|
||||
render() {
|
||||
const error = this.state.error ?
|
||||
<div className="mx_EventTile_tileError mx_EventTile_body">
|
||||
{ _t("Failed to load map") }
|
||||
</div> : null;
|
||||
|
||||
return <div className="mx_MLocationBody">
|
||||
<div id={this.getBodyId()} className="mx_MLocationBody_map" />
|
||||
{ error }
|
||||
<span className="mx_EventTile_body">{ this.description }</span>
|
||||
</div>;
|
||||
}
|
||||
}
|
|
@ -125,6 +125,14 @@ export default class MessageEvent extends React.Component<IProps> implements IMe
|
|||
BodyType = sdk.getComponent('messages.MPollBody');
|
||||
}
|
||||
}
|
||||
|
||||
if ((type && type === "org.matrix.msc3488.location") ||
|
||||
(type && type === EventType.RoomMessage && msgtype && msgtype === MsgType.Location)) {
|
||||
// TODO: tidy this up once location sharing is out of labs
|
||||
if (SettingsStore.getValue("feature_location_share")) {
|
||||
BodyType = sdk.getComponent('messages.MLocationBody');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (SettingsStore.getValue("feature_mjolnir")) {
|
||||
|
|
|
@ -48,6 +48,7 @@ import { ComposerInsertPayload } from "../../../dispatcher/payloads/ComposerInse
|
|||
import { Action } from "../../../dispatcher/actions";
|
||||
import EditorModel from "../../../editor/model";
|
||||
import EmojiPicker from '../emojipicker/EmojiPicker';
|
||||
import LocationPicker from '../location/LocationPicker';
|
||||
import UIStore, { UI_EVENTS } from '../../../stores/UIStore';
|
||||
import Modal from "../../../Modal";
|
||||
import { RelationType } from 'matrix-js-sdk/src/@types/event';
|
||||
|
@ -55,6 +56,9 @@ import RoomContext from '../../../contexts/RoomContext';
|
|||
import { POLL_START_EVENT_TYPE } from "../../../polls/consts";
|
||||
import ErrorDialog from "../dialogs/ErrorDialog";
|
||||
import PollCreateDialog from "../elements/PollCreateDialog";
|
||||
import { MsgType } from "matrix-js-sdk/src/@types/event";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import LocationShareType from "../location/LocationShareType";
|
||||
import { SettingUpdatedPayload } from "../../../dispatcher/payloads/SettingUpdatedPayload";
|
||||
|
||||
let instanceCount = 0;
|
||||
|
@ -77,7 +81,7 @@ function SendButton(props: ISendButtonProps) {
|
|||
|
||||
interface IEmojiButtonProps {
|
||||
addEmoji: (unicode: string) => boolean;
|
||||
menuPosition: any; // TODO: Types
|
||||
menuPosition: AboveLeftOf;
|
||||
narrowMode: boolean;
|
||||
}
|
||||
|
||||
|
@ -114,6 +118,46 @@ const EmojiButton: React.FC<IEmojiButtonProps> = ({ addEmoji, menuPosition, narr
|
|||
</React.Fragment>;
|
||||
};
|
||||
|
||||
interface ILocationButtonProps {
|
||||
room: Room;
|
||||
shareLocation: (uri: string, ts: number, type: LocationShareType, description: string) => boolean;
|
||||
menuPosition: AboveLeftOf;
|
||||
narrowMode: boolean;
|
||||
}
|
||||
|
||||
const LocationButton: React.FC<ILocationButtonProps> = ({ shareLocation, menuPosition, narrowMode }) => {
|
||||
const [menuDisplayed, button, openMenu, closeMenu] = useContextMenu();
|
||||
|
||||
let contextMenu;
|
||||
if (menuDisplayed) {
|
||||
const position = menuPosition ?? aboveLeftOf(button.current.getBoundingClientRect());
|
||||
contextMenu = <ContextMenu {...position} onFinished={closeMenu} managed={false}>
|
||||
<LocationPicker onChoose={shareLocation} onFinished={closeMenu} />
|
||||
</ContextMenu>;
|
||||
}
|
||||
|
||||
const className = classNames(
|
||||
"mx_MessageComposer_button",
|
||||
"mx_MessageComposer_location",
|
||||
{
|
||||
"mx_MessageComposer_button_highlight": menuDisplayed,
|
||||
},
|
||||
);
|
||||
|
||||
// TODO: replace ContextMenuTooltipButton with a unified representation of
|
||||
// the header buttons and the right panel buttons
|
||||
return <React.Fragment>
|
||||
<AccessibleTooltipButton
|
||||
className={className}
|
||||
onClick={openMenu}
|
||||
title={!narrowMode && _t('Share location')}
|
||||
label={narrowMode ? _t('Share location') : null}
|
||||
/>
|
||||
|
||||
{ contextMenu }
|
||||
</React.Fragment>;
|
||||
};
|
||||
|
||||
interface IUploadButtonProps {
|
||||
roomId: string;
|
||||
relation?: IEventRelation | null;
|
||||
|
@ -447,6 +491,25 @@ export default class MessageComposer extends React.Component<IProps, IState> {
|
|||
return true;
|
||||
};
|
||||
|
||||
private shareLocation = (uri: string, ts: number, type: LocationShareType, description: string): boolean => {
|
||||
if (!uri) return false;
|
||||
try {
|
||||
const text = `${description ? description : 'Location'} at ${uri} as of ${new Date(ts).toISOString()}`;
|
||||
// noinspection ES6MissingAwait - we don't care if it fails, it'll get queued.
|
||||
MatrixClientPeg.get().sendMessage(this.props.room.roomId, {
|
||||
"body": text,
|
||||
"msgtype": MsgType.Location,
|
||||
"geo_uri": uri,
|
||||
"org.matrix.msc3488.location": { uri, description },
|
||||
"org.matrix.msc3488.ts": ts,
|
||||
// TODO: MSC1767 fallbacks for text & thumbnail
|
||||
});
|
||||
} catch (e) {
|
||||
logger.error("Error sending location:", e);
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
private sendMessage = async () => {
|
||||
if (this.state.haveRecording && this.voiceRecordingButton.current) {
|
||||
// There shouldn't be any text message to send when a voice recording is active, so
|
||||
|
@ -514,6 +577,17 @@ export default class MessageComposer extends React.Component<IProps, IState> {
|
|||
relation={this.props.relation}
|
||||
/>,
|
||||
);
|
||||
if (SettingsStore.getValue("feature_location_share")) {
|
||||
buttons.push(
|
||||
<LocationButton
|
||||
key="location"
|
||||
room={this.props.room}
|
||||
shareLocation={this.shareLocation}
|
||||
menuPosition={menuPosition}
|
||||
narrowMode={this.state.narrowMode}
|
||||
/>,
|
||||
);
|
||||
}
|
||||
buttons.push(
|
||||
<EmojiButton key="emoji_button" addEmoji={this.addEmoji} menuPosition={menuPosition} narrowMode={this.state.narrowMode} />,
|
||||
);
|
||||
|
|
|
@ -854,6 +854,7 @@
|
|||
"Show message previews for reactions in all rooms": "Show message previews for reactions in all rooms",
|
||||
"Offline encrypted messaging using dehydrated devices": "Offline encrypted messaging using dehydrated devices",
|
||||
"Polls (under active development)": "Polls (under active development)",
|
||||
"Location sharing (under active development)": "Location sharing (under active development)",
|
||||
"Show info about bridges in room settings": "Show info about bridges in room settings",
|
||||
"New layout switcher (with message bubbles)": "New layout switcher (with message bubbles)",
|
||||
"Meta Spaces": "Meta Spaces",
|
||||
|
@ -1649,6 +1650,7 @@
|
|||
"Send message": "Send message",
|
||||
"Emoji picker": "Emoji picker",
|
||||
"Add emoji": "Add emoji",
|
||||
"Share location": "Share location",
|
||||
"Upload file": "Upload file",
|
||||
"You do not have permission to start polls in this room.": "You do not have permission to start polls in this room.",
|
||||
"Create poll": "Create poll",
|
||||
|
@ -2070,6 +2072,7 @@
|
|||
"Declining …": "Declining …",
|
||||
"%(name)s wants to verify": "%(name)s wants to verify",
|
||||
"You sent a verification request": "You sent a verification request",
|
||||
"Failed to load map": "Failed to load map",
|
||||
"Vote not registered": "Vote not registered",
|
||||
"Sorry, your vote was not registered. Please try again.": "Sorry, your vote was not registered. Please try again.",
|
||||
"No votes cast": "No votes cast",
|
||||
|
@ -2100,6 +2103,9 @@
|
|||
"edited": "edited",
|
||||
"Submit logs": "Submit logs",
|
||||
"Can't load this message": "Can't load this message",
|
||||
"Share my current location as a once off": "Share my current location as a once off",
|
||||
"My location": "My location",
|
||||
"Type of location share": "Type of location share",
|
||||
"Failed to load group members": "Failed to load group members",
|
||||
"Filter community members": "Filter community members",
|
||||
"Are you sure you want to remove '%(roomName)s' from %(groupId)s?": "Are you sure you want to remove '%(roomName)s' from %(groupId)s?",
|
||||
|
|
|
@ -307,6 +307,13 @@ export const SETTINGS: {[setting: string]: ISetting} = {
|
|||
displayName: _td("Polls (under active development)"),
|
||||
default: false,
|
||||
},
|
||||
"feature_location_share": {
|
||||
isFeature: true,
|
||||
labsGroup: LabGroup.Messaging,
|
||||
supportedLevels: LEVELS_FEATURE,
|
||||
displayName: _td("Location sharing (under active development)"),
|
||||
default: false,
|
||||
},
|
||||
"doNotDisturb": {
|
||||
supportedLevels: [SettingLevel.DEVICE],
|
||||
default: false,
|
||||
|
|
|
@ -54,6 +54,8 @@ export default abstract class SettingController {
|
|||
*/
|
||||
public onChange(level: SettingLevel, roomId: string, newValue: any) {
|
||||
// do nothing by default
|
||||
|
||||
// FIXME: force a fresh on the RoomView for the roomId in question
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -15,3 +15,5 @@ global.TextDecoder = TextDecoder;
|
|||
|
||||
configure({ adapter: new Adapter() });
|
||||
|
||||
// maplibre requires a createObjectURL mock
|
||||
global.URL.createObjectURL = jest.fn();
|
||||
|
|
182
yarn.lock
182
yarn.lock
|
@ -1306,6 +1306,56 @@
|
|||
"@types/yargs" "^15.0.0"
|
||||
chalk "^4.0.0"
|
||||
|
||||
"@mapbox/geojson-rewind@^0.5.0":
|
||||
version "0.5.1"
|
||||
resolved "https://registry.yarnpkg.com/@mapbox/geojson-rewind/-/geojson-rewind-0.5.1.tgz#adbe16dc683eb40e90934c51a5e28c7bbf44f4e1"
|
||||
integrity sha512-eL7fMmfTBKjrb+VFHXCGv9Ot0zc3C0U+CwXo1IrP+EPwDczLoXv34Tgq3y+2mPSFNVUXgU42ILWJTC7145KPTA==
|
||||
dependencies:
|
||||
get-stream "^6.0.1"
|
||||
minimist "^1.2.5"
|
||||
|
||||
"@mapbox/geojson-types@^1.0.2":
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@mapbox/geojson-types/-/geojson-types-1.0.2.tgz#9aecf642cb00eab1080a57c4f949a65b4a5846d6"
|
||||
integrity sha512-e9EBqHHv3EORHrSfbR9DqecPNn+AmuAoQxV6aL8Xu30bJMJR1o8PZLZzpk1Wq7/NfCbuhmakHTPYRhoqLsXRnw==
|
||||
|
||||
"@mapbox/jsonlint-lines-primitives@^2.0.2":
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@mapbox/jsonlint-lines-primitives/-/jsonlint-lines-primitives-2.0.2.tgz#ce56e539f83552b58d10d672ea4d6fc9adc7b234"
|
||||
integrity sha1-zlblOfg1UrWNENZy6k1vya3HsjQ=
|
||||
|
||||
"@mapbox/mapbox-gl-supported@^1.5.0":
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@mapbox/mapbox-gl-supported/-/mapbox-gl-supported-1.5.0.tgz#f60b6a55a5d8e5ee908347d2ce4250b15103dc8e"
|
||||
integrity sha512-/PT1P6DNf7vjEEiPkVIRJkvibbqWtqnyGaBz3nfRdcxclNSnSdaLU5tfAgcD7I8Yt5i+L19s406YLl1koLnLbg==
|
||||
|
||||
"@mapbox/point-geometry@0.1.0", "@mapbox/point-geometry@^0.1.0", "@mapbox/point-geometry@~0.1.0":
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@mapbox/point-geometry/-/point-geometry-0.1.0.tgz#8a83f9335c7860effa2eeeca254332aa0aeed8f2"
|
||||
integrity sha1-ioP5M1x4YO/6Lu7KJUMyqgru2PI=
|
||||
|
||||
"@mapbox/tiny-sdf@^1.1.1":
|
||||
version "1.2.5"
|
||||
resolved "https://registry.yarnpkg.com/@mapbox/tiny-sdf/-/tiny-sdf-1.2.5.tgz#424c620a96442b20402552be70a7f62a8407cc59"
|
||||
integrity sha512-cD8A/zJlm6fdJOk6DqPUV8mcpyJkRz2x2R+/fYcWDYG3oWbG7/L7Yl/WqQ1VZCjnL9OTIMAn6c+BC5Eru4sQEw==
|
||||
|
||||
"@mapbox/unitbezier@^0.0.0":
|
||||
version "0.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@mapbox/unitbezier/-/unitbezier-0.0.0.tgz#15651bd553a67b8581fb398810c98ad86a34524e"
|
||||
integrity sha1-FWUb1VOme4WB+zmIEMmK2Go0Uk4=
|
||||
|
||||
"@mapbox/vector-tile@^1.3.1":
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@mapbox/vector-tile/-/vector-tile-1.3.1.tgz#d3a74c90402d06e89ec66de49ec817ff53409666"
|
||||
integrity sha512-MCEddb8u44/xfQ3oD+Srl/tNcQoqTw3goGk2oLsrFxOTc3dUp+kAnby3PvAeeBYSMSjSPD1nd1AJA6W49WnoUw==
|
||||
dependencies:
|
||||
"@mapbox/point-geometry" "~0.1.0"
|
||||
|
||||
"@mapbox/whoots-js@^3.1.0":
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@mapbox/whoots-js/-/whoots-js-3.1.0.tgz#497c67a1cef50d1a2459ba60f315e448d2ad87fe"
|
||||
integrity sha512-Es6WcD0nO5l+2BOQS4uLfNPYQaNDfbot3X1XUoloz+x0mPDS3eeORZJl06HXjwBG1fOGwCRnzK88LMdxKRrd6Q==
|
||||
|
||||
"@matrix-org/olm@https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.3.tgz":
|
||||
version "3.2.3"
|
||||
resolved "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.3.tgz#cc332fdd25c08ef0e40f4d33fc3f822a0f98b6f4"
|
||||
|
@ -1672,6 +1722,11 @@
|
|||
"@types/fbemitter" "*"
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/geojson@^7946.0.8":
|
||||
version "7946.0.8"
|
||||
resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.8.tgz#30744afdb385e2945e22f3b033f897f76b1f12ca"
|
||||
integrity sha512-1rkryxURpr6aWP7R786/UQOkJ3PcpQiWkAXBmdWc7ryFWqN6a4xfK7BtjXvFBKO9LjQ+MWQSWxYeZX1OApnArA==
|
||||
|
||||
"@types/graceful-fs@^4.1.2":
|
||||
version "4.1.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.5.tgz#21ffba0d98da4350db64891f92a9e5db3cdb4e15"
|
||||
|
@ -2996,6 +3051,11 @@ css-what@^5.0.0, css-what@^5.0.1:
|
|||
resolved "https://registry.yarnpkg.com/css-what/-/css-what-5.1.0.tgz#3f7b707aadf633baf62c2ceb8579b545bb40f7fe"
|
||||
integrity sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw==
|
||||
|
||||
csscolorparser@~1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/csscolorparser/-/csscolorparser-1.0.3.tgz#b34f391eea4da8f3e98231e2ccd8df9c041f171b"
|
||||
integrity sha1-s085HupNqPPpgjHizNjfnAQfFxs=
|
||||
|
||||
cssesc@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee"
|
||||
|
@ -3277,6 +3337,11 @@ domutils@^2.5.2, domutils@^2.6.0, domutils@^2.7.0:
|
|||
domelementtype "^2.2.0"
|
||||
domhandler "^4.2.0"
|
||||
|
||||
earcut@^2.2.2:
|
||||
version "2.2.3"
|
||||
resolved "https://registry.yarnpkg.com/earcut/-/earcut-2.2.3.tgz#d44ced2ff5a18859568e327dd9c7d46b16f55cf4"
|
||||
integrity sha512-iRDI1QeCQIhMCZk48DRDMVgQSSBDmbzzNhnxIo+pwx3swkfjMh6vh0nWLq1NdvGHLKH6wIrAM3vQWeTj6qeoug==
|
||||
|
||||
ecc-jsbn@~0.1.1:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9"
|
||||
|
@ -4112,6 +4177,11 @@ gensync@^1.0.0-beta.2:
|
|||
resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0"
|
||||
integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==
|
||||
|
||||
geojson-vt@^3.2.1:
|
||||
version "3.2.1"
|
||||
resolved "https://registry.yarnpkg.com/geojson-vt/-/geojson-vt-3.2.1.tgz#f8adb614d2c1d3f6ee7c4265cad4bbf3ad60c8b7"
|
||||
integrity sha512-EvGQQi/zPrDA6zr6BnJD/YhwAkBP8nnJ9emh3EnHQKVMfg/MRVtPbMYdgVy/IaEmn4UfagD2a6fafPDL5hbtwg==
|
||||
|
||||
get-caller-file@^2.0.1, get-caller-file@^2.0.5:
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
|
||||
|
@ -4150,6 +4220,11 @@ get-stream@^5.0.0:
|
|||
dependencies:
|
||||
pump "^3.0.0"
|
||||
|
||||
get-stream@^6.0.1:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7"
|
||||
integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==
|
||||
|
||||
get-symbol-description@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6"
|
||||
|
@ -4175,6 +4250,11 @@ gfm.css@^1.1.2:
|
|||
resolved "https://registry.yarnpkg.com/gfm.css/-/gfm.css-1.1.2.tgz#94acfa600672663b9dd0fd4b6ee5d11c8dbc161e"
|
||||
integrity sha512-KhK3rqxMj+UTLRxWnfUA5n8XZYMWfHrrcCxtWResYR2B3hWIqBM6v9FPGZSlVuX+ScLewizOvNkjYXuPs95ThQ==
|
||||
|
||||
gl-matrix@^3.2.1:
|
||||
version "3.4.3"
|
||||
resolved "https://registry.yarnpkg.com/gl-matrix/-/gl-matrix-3.4.3.tgz#fc1191e8320009fd4d20e9339595c6041ddc22c9"
|
||||
integrity sha512-wcCp8vu8FT22BnvKVPjXa/ICBWRq/zjFfdofZy1WSpQZpphblv12/bOQLBC1rMM7SGOFS9ltVmKOHil5+Ml7gA==
|
||||
|
||||
glob-parent@^5.0.0, glob-parent@^5.1.2, glob-parent@~5.1.2:
|
||||
version "5.1.2"
|
||||
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
|
||||
|
@ -4256,6 +4336,11 @@ graceful-fs@^4.2.4:
|
|||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a"
|
||||
integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==
|
||||
|
||||
grid-index@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/grid-index/-/grid-index-1.1.0.tgz#97f8221edec1026c8377b86446a7c71e79522ea7"
|
||||
integrity sha512-HZRwumpOGUrHyxO5bqKZL0B0GlUpwtCAzZ42sgxUPniu33R1LSFH5yrIcBCHjkctCAh3mtWKcKd9J4vDDdeVHA==
|
||||
|
||||
growly@^1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081"
|
||||
|
@ -4465,7 +4550,7 @@ iconv-lite@^0.6.2:
|
|||
dependencies:
|
||||
safer-buffer ">= 2.1.2 < 3.0.0"
|
||||
|
||||
ieee754@^1.1.13:
|
||||
ieee754@^1.1.12, ieee754@^1.1.13:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
|
||||
integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
|
||||
|
@ -5638,6 +5723,11 @@ katex@^0.12.0:
|
|||
dependencies:
|
||||
commander "^2.19.0"
|
||||
|
||||
kdbush@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/kdbush/-/kdbush-3.0.0.tgz#f8484794d47004cc2d85ed3a79353dbe0abc2bf0"
|
||||
integrity sha512-hRkd6/XW4HTsA9vjVpY9tuXJYLSlelnkTmVFu4M9/7MIYQtFcHpbugAU7UbOfjOiVSVYl2fqgBuJ32JUmRo5Ew==
|
||||
|
||||
kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0:
|
||||
version "3.2.2"
|
||||
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64"
|
||||
|
@ -5864,6 +5954,35 @@ map-visit@^1.0.0:
|
|||
dependencies:
|
||||
object-visit "^1.0.0"
|
||||
|
||||
maplibre-gl@^1.15.2:
|
||||
version "1.15.2"
|
||||
resolved "https://registry.yarnpkg.com/maplibre-gl/-/maplibre-gl-1.15.2.tgz#7fb47868b62455af916c090903f2154394450f9c"
|
||||
integrity sha512-uPeV530apb4JfX3cRFfE+awFnbcJTOnCv2QvY4mw4huiInbybElWYkNzTs324YLSADq0f4bidRoYcR81ho3aLA==
|
||||
dependencies:
|
||||
"@mapbox/geojson-rewind" "^0.5.0"
|
||||
"@mapbox/geojson-types" "^1.0.2"
|
||||
"@mapbox/jsonlint-lines-primitives" "^2.0.2"
|
||||
"@mapbox/mapbox-gl-supported" "^1.5.0"
|
||||
"@mapbox/point-geometry" "^0.1.0"
|
||||
"@mapbox/tiny-sdf" "^1.1.1"
|
||||
"@mapbox/unitbezier" "^0.0.0"
|
||||
"@mapbox/vector-tile" "^1.3.1"
|
||||
"@mapbox/whoots-js" "^3.1.0"
|
||||
csscolorparser "~1.0.3"
|
||||
earcut "^2.2.2"
|
||||
geojson-vt "^3.2.1"
|
||||
gl-matrix "^3.2.1"
|
||||
grid-index "^1.1.0"
|
||||
minimist "^1.2.5"
|
||||
murmurhash-js "^1.0.0"
|
||||
pbf "^3.2.1"
|
||||
potpack "^1.0.1"
|
||||
quickselect "^2.0.0"
|
||||
rw "^1.3.3"
|
||||
supercluster "^7.1.0"
|
||||
tinyqueue "^2.0.3"
|
||||
vt-pbf "^3.1.1"
|
||||
|
||||
mathml-tag-names@^2.1.3:
|
||||
version "2.1.3"
|
||||
resolved "https://registry.yarnpkg.com/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz#4ddadd67308e780cf16a47685878ee27b736a0a3"
|
||||
|
@ -6101,6 +6220,11 @@ ms@2.1.2:
|
|||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
|
||||
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
|
||||
|
||||
murmurhash-js@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/murmurhash-js/-/murmurhash-js-1.0.0.tgz#b06278e21fc6c37fa5313732b0412bcb6ae15f51"
|
||||
integrity sha1-sGJ44h/Gw3+lMTcysEEry2rhX1E=
|
||||
|
||||
nanoid@^3.1.28:
|
||||
version "3.1.30"
|
||||
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.30.tgz#63f93cc548d2a113dc5dfbc63bfa09e2b9b64362"
|
||||
|
@ -6570,6 +6694,14 @@ path-type@^4.0.0:
|
|||
resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
|
||||
integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
|
||||
|
||||
pbf@^3.2.1:
|
||||
version "3.2.1"
|
||||
resolved "https://registry.yarnpkg.com/pbf/-/pbf-3.2.1.tgz#b4c1b9e72af966cd82c6531691115cc0409ffe2a"
|
||||
integrity sha512-ClrV7pNOn7rtmoQVF4TS1vyU0WhYRnP92fzbfF75jAIwpnzdJXf8iTd4CMEqO4yUenH6NDqLiwjqlh6QgZzgLQ==
|
||||
dependencies:
|
||||
ieee754 "^1.1.12"
|
||||
resolve-protobuf-schema "^2.1.0"
|
||||
|
||||
performance-now@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
|
||||
|
@ -6731,6 +6863,11 @@ posthog-js@1.12.2:
|
|||
dependencies:
|
||||
fflate "^0.4.1"
|
||||
|
||||
potpack@^1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/potpack/-/potpack-1.0.2.tgz#23b99e64eb74f5741ffe7656b5b5c4ddce8dfc14"
|
||||
integrity sha512-choctRBIV9EMT9WGAZHn3V7t0Z2pMQyl0EZE6pFc/6ml3ssw7Dlf/oAOvFwjm1HVsqfQN8GfeFyJ+d8tRzqueQ==
|
||||
|
||||
prelude-ls@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
|
||||
|
@ -6790,6 +6927,11 @@ prop-types@^15.6.2, prop-types@^15.7.0, prop-types@^15.7.2:
|
|||
object-assign "^4.1.1"
|
||||
react-is "^16.8.1"
|
||||
|
||||
protocol-buffers-schema@^3.3.1:
|
||||
version "3.6.0"
|
||||
resolved "https://registry.yarnpkg.com/protocol-buffers-schema/-/protocol-buffers-schema-3.6.0.tgz#77bc75a48b2ff142c1ad5b5b90c94cd0fa2efd03"
|
||||
integrity sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw==
|
||||
|
||||
psl@^1.1.28, psl@^1.1.33:
|
||||
version "1.8.0"
|
||||
resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24"
|
||||
|
@ -6865,6 +7007,11 @@ quick-lru@^4.0.1:
|
|||
resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-4.0.1.tgz#5b8878f113a58217848c6482026c73e1ba57727f"
|
||||
integrity sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==
|
||||
|
||||
quickselect@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/quickselect/-/quickselect-2.0.0.tgz#f19680a486a5eefb581303e023e98faaf25dd018"
|
||||
integrity sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw==
|
||||
|
||||
raf-schd@^4.0.2:
|
||||
version "4.0.3"
|
||||
resolved "https://registry.yarnpkg.com/raf-schd/-/raf-schd-4.0.3.tgz#5d6c34ef46f8b2a0e880a8fcdb743efc5bfdbc1a"
|
||||
|
@ -7262,6 +7409,13 @@ resolve-from@^5.0.0:
|
|||
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69"
|
||||
integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==
|
||||
|
||||
resolve-protobuf-schema@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/resolve-protobuf-schema/-/resolve-protobuf-schema-2.1.0.tgz#9ca9a9e69cf192bbdaf1006ec1973948aa4a3758"
|
||||
integrity sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ==
|
||||
dependencies:
|
||||
protocol-buffers-schema "^3.3.1"
|
||||
|
||||
resolve-url@^0.2.1:
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a"
|
||||
|
@ -7335,6 +7489,11 @@ run-parallel@^1.1.9:
|
|||
dependencies:
|
||||
queue-microtask "^1.2.2"
|
||||
|
||||
rw@^1.3.3:
|
||||
version "1.3.3"
|
||||
resolved "https://registry.yarnpkg.com/rw/-/rw-1.3.3.tgz#3f862dfa91ab766b14885ef4d01124bfda074fb4"
|
||||
integrity sha1-P4Yt+pGrdmsUiF700BEkv9oHT7Q=
|
||||
|
||||
rxjs@^6.5.2:
|
||||
version "6.6.7"
|
||||
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9"
|
||||
|
@ -7915,6 +8074,13 @@ sugarss@^2.0.0:
|
|||
dependencies:
|
||||
postcss "^7.0.2"
|
||||
|
||||
supercluster@^7.1.0:
|
||||
version "7.1.4"
|
||||
resolved "https://registry.yarnpkg.com/supercluster/-/supercluster-7.1.4.tgz#6762aabfd985d3390b49f13b815567d5116a828a"
|
||||
integrity sha512-GhKkRM1jMR6WUwGPw05fs66pOFWhf59lXq+Q3J3SxPvhNcmgOtLRV6aVQPMRsmXdpaeFJGivt+t7QXUPL3ff4g==
|
||||
dependencies:
|
||||
kdbush "^3.0.0"
|
||||
|
||||
supports-color@^5.3.0:
|
||||
version "5.5.0"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
|
||||
|
@ -8011,6 +8177,11 @@ tiny-invariant@^1.0.6:
|
|||
resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.1.0.tgz#634c5f8efdc27714b7f386c35e6760991d230875"
|
||||
integrity sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw==
|
||||
|
||||
tinyqueue@^2.0.3:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/tinyqueue/-/tinyqueue-2.0.3.tgz#64d8492ebf39e7801d7bd34062e29b45b2035f08"
|
||||
integrity sha512-ppJZNDuKGgxzkHihX8v9v9G5f+18gzaTfrukGrq6ueg0lmH4nqVnA2IPG0AEH3jKEk2GRJCUhDoqpoiw3PHLBA==
|
||||
|
||||
tmatch@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/tmatch/-/tmatch-2.0.1.tgz#0c56246f33f30da1b8d3d72895abaf16660f38cf"
|
||||
|
@ -8406,6 +8577,15 @@ vfile@^4.0.0:
|
|||
unist-util-stringify-position "^2.0.0"
|
||||
vfile-message "^2.0.0"
|
||||
|
||||
vt-pbf@^3.1.1:
|
||||
version "3.1.3"
|
||||
resolved "https://registry.yarnpkg.com/vt-pbf/-/vt-pbf-3.1.3.tgz#68fd150756465e2edae1cc5c048e063916dcfaac"
|
||||
integrity sha512-2LzDFzt0mZKZ9IpVF2r69G9bXaP2Q2sArJCmcCgvfTdCCZzSyz4aCLoQyUilu37Ll56tCblIZrXFIjNUpGIlmA==
|
||||
dependencies:
|
||||
"@mapbox/point-geometry" "0.1.0"
|
||||
"@mapbox/vector-tile" "^1.3.1"
|
||||
pbf "^3.2.1"
|
||||
|
||||
w3c-hr-time@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd"
|
||||
|
|
Loading…
Reference in New Issue