diff --git a/src/components/views/location/LocationButton.tsx b/src/components/views/location/LocationButton.tsx index 26f5bda13f..e6a6f8d92e 100644 --- a/src/components/views/location/LocationButton.tsx +++ b/src/components/views/location/LocationButton.tsx @@ -17,6 +17,7 @@ limitations under the License. import React, { ReactElement, SyntheticEvent, useContext } from 'react'; import classNames from 'classnames'; import { RoomMember } from 'matrix-js-sdk/src/models/room-member'; +import { IEventRelation } from 'matrix-js-sdk/src/models/event'; import { _t } from '../../../languageHandler'; import { CollapsibleButton } from '../rooms/CollapsibleButton'; @@ -28,9 +29,10 @@ interface IProps { roomId: string; sender: RoomMember; menuPosition: AboveLeftOf; + relation?: IEventRelation; } -export const LocationButton: React.FC = ({ roomId, sender, menuPosition }) => { +export const LocationButton: React.FC = ({ roomId, sender, menuPosition, relation }) => { const overflowMenuCloser = useContext(OverflowMenuContext); const [menuDisplayed, button, openMenu, closeMenu] = useContextMenu(); @@ -49,7 +51,9 @@ export const LocationButton: React.FC = ({ roomId, sender, menuPosition onFinished={_onFinished} sender={sender} roomId={roomId} - openMenu={openMenu} />; + openMenu={openMenu} + relation={relation} + />; } const className = classNames( diff --git a/src/components/views/location/LocationPicker.tsx b/src/components/views/location/LocationPicker.tsx index ea3e4f51f0..2300ba7ac6 100644 --- a/src/components/views/location/LocationPicker.tsx +++ b/src/components/views/location/LocationPicker.tsx @@ -32,7 +32,7 @@ import { tileServerFromWellKnown } from '../../../utils/WellKnownUtils'; export interface ILocationPickerProps { sender: RoomMember; - onChoose(uri: string, ts: number): boolean; + onChoose(uri: string, ts: number): unknown; onFinished(ev?: SyntheticEvent): void; } @@ -159,10 +159,7 @@ class LocationPicker extends React.Component { private onOk = () => { const position = this.state.position; - this.props.onChoose( - position ? getGeoUri(position) : undefined, - position ? position.timestamp : undefined, - ); + this.props.onChoose(position ? getGeoUri(position) : undefined, position?.timestamp); this.props.onFinished(); }; diff --git a/src/components/views/location/LocationShareMenu.tsx b/src/components/views/location/LocationShareMenu.tsx index 52cf32a217..1f29b48291 100644 --- a/src/components/views/location/LocationShareMenu.tsx +++ b/src/components/views/location/LocationShareMenu.tsx @@ -16,6 +16,7 @@ limitations under the License. import React, { SyntheticEvent, useContext, useState } from 'react'; import { Room } from 'matrix-js-sdk/src/models/room'; +import { IEventRelation } from 'matrix-js-sdk/src/models/event'; import MatrixClientContext from '../../../contexts/MatrixClientContext'; import ContextMenu, { AboveLeftOf } from '../../structures/ContextMenu'; @@ -29,6 +30,7 @@ type Props = Omit & { menuPosition: AboveLeftOf; openMenu: () => void; roomId: Room["roomId"]; + relation?: IEventRelation; }; const getEnabledShareTypes = (): LocationShareType[] => { @@ -43,7 +45,12 @@ const getEnabledShareTypes = (): LocationShareType[] => { }; const LocationShareMenu: React.FC = ({ - menuPosition, onFinished, sender, roomId, openMenu, + menuPosition, + onFinished, + sender, + roomId, + openMenu, + relation, }) => { const matrixClient = useContext(MatrixClientContext); const enabledShareTypes = getEnabledShareTypes(); @@ -60,7 +67,7 @@ const LocationShareMenu: React.FC = ({
{ shareType ? : diff --git a/src/components/views/location/shareLocation.ts b/src/components/views/location/shareLocation.ts index 90733810b3..bd98f2ea8b 100644 --- a/src/components/views/location/shareLocation.ts +++ b/src/components/views/location/shareLocation.ts @@ -14,43 +14,49 @@ See the License for the specific language governing permissions and limitations under the License. */ +import { RelationType } from "matrix-js-sdk/src/@types/event"; import { MatrixClient } from "matrix-js-sdk/src/client"; import { makeLocationContent } from "matrix-js-sdk/src/content-helpers"; import { logger } from "matrix-js-sdk/src/logger"; +import { IEventRelation } from "matrix-js-sdk/src/models/event"; import { _t } from "../../../languageHandler"; import Modal from "../../../Modal"; import QuestionDialog from "../dialogs/QuestionDialog"; +import SdkConfig from "../../../SdkConfig"; -export const shareLocation = (client: MatrixClient, roomId: string, openMenu: () => void) => - (uri: string, ts: number) => { - if (!uri) return false; - try { - const text = textForLocation(uri, ts, null); - client.sendMessage( - roomId, - makeLocationContent(text, uri, ts, null), - ); - } catch (e) { - logger.error("We couldn’t send your location", e); +export const shareLocation = ( + client: MatrixClient, + roomId: string, + relation: IEventRelation | undefined, + openMenu: () => void, +) => async (uri: string, ts: number) => { + if (!uri) return false; + try { + const text = textForLocation(uri, ts, null); + const threadId = relation?.rel_type === RelationType.Thread ? relation.event_id : null; + await client.sendMessage(roomId, threadId, makeLocationContent(text, uri, ts, null)); + } catch (e) { + logger.error("We couldn't send your location", e); - const analyticsAction = 'We couldn’t send your location'; - const params = { - title: _t("We couldn’t send your location"), - description: _t( - "Element could not send your location. Please try again later."), - button: _t('Try again'), - cancelButton: _t('Cancel'), - onFinished: (tryAgain: boolean) => { - if (tryAgain) { - openMenu(); - } - }, - }; - Modal.createTrackedDialog(analyticsAction, '', QuestionDialog, params); - } - return true; - }; + const analyticsAction = "We couldn't send your location"; + const params = { + title: _t("We couldn't send your location"), + description: _t("%(brand)s could not send your location. Please try again later.", { + brand: SdkConfig.get().brand, + }), + button: _t('Try again'), + cancelButton: _t('Cancel'), + onFinished: (tryAgain: boolean) => { + if (tryAgain) { + openMenu(); + } + }, + }; + Modal.createTrackedDialog(analyticsAction, '', QuestionDialog, params); + } + return true; +}; export function textForLocation( uri: string, diff --git a/src/components/views/rooms/EventTile.tsx b/src/components/views/rooms/EventTile.tsx index 645bbbd3c5..df617254d6 100644 --- a/src/components/views/rooms/EventTile.tsx +++ b/src/components/views/rooms/EventTile.tsx @@ -399,7 +399,7 @@ export default class EventTile extends React.Component { thread, threadReplyCount: thread?.length, threadLastReply: thread?.replyToEvent, - threadLastSender: thread?.replyToEvent.sender, + threadLastSender: thread?.replyToEvent?.sender, }; // don't do RR animations until we are mounted diff --git a/src/components/views/rooms/MessageComposerButtons.tsx b/src/components/views/rooms/MessageComposerButtons.tsx index a66422bbab..7a16b23937 100644 --- a/src/components/views/rooms/MessageComposerButtons.tsx +++ b/src/components/views/rooms/MessageComposerButtons.tsx @@ -361,6 +361,7 @@ function showLocationButton( ? diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 246658d5c3..41944c4d68 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -2177,8 +2177,8 @@ "Failed to fetch your location. Please try again later.": "Failed to fetch your location. Please try again later.", "Timed out trying to fetch your location. Please try again later.": "Timed out trying to fetch your location. Please try again later.", "Unknown error fetching location. Please try again later.": "Unknown error fetching location. Please try again later.", - "We couldn’t send your location": "We couldn’t send your location", - "Element could not send your location. Please try again later.": "Element could not send your location. Please try again later.", + "We couldn't send your location": "We couldn't send your location", + "%(brand)s could not send your location. Please try again later.": "%(brand)s could not send your location. Please try again later.", "My current location": "My current location", "My live location": "My live location", "Drop a Pin": "Drop a Pin",