diff --git a/src/components/views/location/LocationButton.tsx b/src/components/views/location/LocationButton.tsx index 2281d87f6b..4ef0e744b1 100644 --- a/src/components/views/location/LocationButton.tsx +++ b/src/components/views/location/LocationButton.tsx @@ -14,26 +14,33 @@ See the License for the specific language governing permissions and limitations under the License. */ -import React, { ReactElement } from 'react'; +import React, { ReactElement, useContext } from 'react'; import classNames from 'classnames'; import { RoomMember } from 'matrix-js-sdk/src/models/room-member'; +import { logger } from "matrix-js-sdk/src/logger"; +import { MatrixClient } from 'matrix-js-sdk/src/client'; +import { makeLocationContent } from "matrix-js-sdk/src/content-helpers"; import { _t } from '../../../languageHandler'; import LocationPicker from './LocationPicker'; import { CollapsibleButton, ICollapsibleButtonProps } from '../rooms/CollapsibleButton'; import ContextMenu, { aboveLeftOf, useContextMenu, AboveLeftOf } from "../../structures/ContextMenu"; +import Modal from '../../../Modal'; +import QuestionDialog from '../dialogs/QuestionDialog'; +import MatrixClientContext from '../../../contexts/MatrixClientContext'; interface IProps extends Pick { + roomId: string; sender: RoomMember; - shareLocation: (uri: string, ts: number) => boolean; menuPosition: AboveLeftOf; narrowMode: boolean; } export const LocationButton: React.FC = ( - { sender, shareLocation, menuPosition, narrowMode }, + { roomId, sender, menuPosition, narrowMode }, ) => { const [menuDisplayed, button, openMenu, closeMenu] = useContextMenu(); + const matrixClient = useContext(MatrixClientContext); let contextMenu: ReactElement; if (menuDisplayed) { @@ -47,7 +54,7 @@ export const LocationButton: React.FC = ( > ; @@ -75,6 +82,36 @@ export const LocationButton: React.FC = ( ; }; +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); + + 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; + }; + export function textForLocation( uri: string, ts: number, diff --git a/src/components/views/rooms/MessageComposer.tsx b/src/components/views/rooms/MessageComposer.tsx index bc9b60f4a4..21d1cecedb 100644 --- a/src/components/views/rooms/MessageComposer.tsx +++ b/src/components/views/rooms/MessageComposer.tsx @@ -19,9 +19,7 @@ import { MatrixEvent, IEventRelation } from "matrix-js-sdk/src/models/event"; import { Room } from "matrix-js-sdk/src/models/room"; import { RoomMember } from "matrix-js-sdk/src/models/room-member"; import { RelationType } from 'matrix-js-sdk/src/@types/event'; -import { logger } from "matrix-js-sdk/src/logger"; import { POLL_START_EVENT_TYPE } from "matrix-js-sdk/src/@types/polls"; -import { makeLocationContent } from "matrix-js-sdk/src/content-helpers"; import { _t } from '../../../languageHandler'; import { MatrixClientPeg } from '../../../MatrixClientPeg'; @@ -60,7 +58,7 @@ import ErrorDialog from "../dialogs/ErrorDialog"; import PollCreateDialog from "../elements/PollCreateDialog"; import { SettingUpdatedPayload } from "../../../dispatcher/payloads/SettingUpdatedPayload"; import { CollapsibleButton, ICollapsibleButtonProps } from './CollapsibleButton'; -import { LocationButton, textForLocation } from '../location/LocationButton'; +import LocationButton from '../location/LocationButton'; let instanceCount = 0; const NARROW_MODE_BREAKPOINT = 500; @@ -452,20 +450,6 @@ export default class MessageComposer extends React.Component { return true; }; - private shareLocation = (uri: string, ts: number): boolean => { - if (!uri) return false; - try { - const text = textForLocation(uri, ts, null); - MatrixClientPeg.get().sendMessage( - this.props.room.roomId, - makeLocationContent(text, uri, ts, null), - ); - } 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 @@ -530,11 +514,14 @@ export default class MessageComposer extends React.Component { , ); if (SettingsStore.getValue("feature_location_share")) { + const sender = this.props.room.getMember( + MatrixClientPeg.get().getUserId(), + ); buttons.push( , diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 9a2c328973..e175b92832 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -2135,6 +2135,8 @@ "Can't load this message": "Can't load this message", "toggle event": "toggle event", "Share location": "Share location", + "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.", "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?",