From 9cb8ce7c20eef87918a60a0573ac1e02a0318ca4 Mon Sep 17 00:00:00 2001 From: Andy Balaam Date: Mon, 10 Jan 2022 09:30:24 +0000 Subject: [PATCH] Add zoom buttons to the location view (#7482) --- .../views/dialogs/_LocationViewDialog.scss | 46 +++++++++++++++++-- res/img/element-icons/minus-button.svg | 3 ++ res/img/element-icons/plus-button.svg | 3 ++ .../views/location/LocationViewDialog.tsx | 15 +++++- .../views/messages/MLocationBody.tsx | 39 +++++++++++++++- src/i18n/strings/en_EN.json | 4 +- 6 files changed, 102 insertions(+), 8 deletions(-) create mode 100644 res/img/element-icons/minus-button.svg create mode 100644 res/img/element-icons/plus-button.svg diff --git a/res/css/views/dialogs/_LocationViewDialog.scss b/res/css/views/dialogs/_LocationViewDialog.scss index 4c37090f72..e7cdaf8800 100644 --- a/res/css/views/dialogs/_LocationViewDialog.scss +++ b/res/css/views/dialogs/_LocationViewDialog.scss @@ -49,8 +49,48 @@ limitations under the License. } } - .mx_MLocationBody .mx_MLocationBody_map { - width: 80vw; - height: 80vh; + .mx_MLocationBody { + position: absolute; + + .mx_MLocationBody_map { + width: 80vw; + height: 80vh; + } + + .mx_MLocationBody_zoomButtons { + position: absolute; + display: grid; + grid-template-columns: auto; + grid-row-gap: 8px; + + right: 24px; + bottom: 48px; + + .mx_AccessibleButton { + background-color: $background; + box-shadow: 0px 4px 12px rgba(0, 0, 0, 0.25); + border-radius: 4px; + width: 24px; + height: 24px; + + .mx_MLocationBody_zoomButton { + background-color: $primary-content; + margin: 4px; + width: 16px; + height: 16px; + mask-repeat: no-repeat; + mask-size: contain; + mask-position: center; + } + + .mx_MLocationBody_plusButton { + mask-image: url('$(res)/img/element-icons/plus-button.svg'); + } + + .mx_MLocationBody_minusButton { + mask-image: url('$(res)/img/element-icons/minus-button.svg'); + } + } + } } } diff --git a/res/img/element-icons/minus-button.svg b/res/img/element-icons/minus-button.svg new file mode 100644 index 0000000000..ca61c23b76 --- /dev/null +++ b/res/img/element-icons/minus-button.svg @@ -0,0 +1,3 @@ + + + diff --git a/res/img/element-icons/plus-button.svg b/res/img/element-icons/plus-button.svg new file mode 100644 index 0000000000..cbc25c4553 --- /dev/null +++ b/res/img/element-icons/plus-button.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/components/views/location/LocationViewDialog.tsx b/src/components/views/location/LocationViewDialog.tsx index 87ea6576ba..438f6a5f16 100644 --- a/src/components/views/location/LocationViewDialog.tsx +++ b/src/components/views/location/LocationViewDialog.tsx @@ -33,11 +33,13 @@ interface IState { @replaceableComponent("views.location.LocationViewDialog") export default class LocationViewDialog extends React.Component { private coords: GeolocationCoordinates; + private map?: maplibregl.Map; constructor(props: IProps) { super(props); this.coords = parseGeoUri(locationEventGeoUri(this.props.mxEvent)); + this.map = null; this.state = { error: undefined, }; @@ -48,7 +50,7 @@ export default class LocationViewDialog extends React.Component return; } - createMap( + this.map = createMap( this.coords, true, this.getBodyId(), @@ -65,6 +67,14 @@ export default class LocationViewDialog extends React.Component return `mx_MLocationViewDialog_marker_${this.props.mxEvent.getId()}`; }; + private onZoomIn = () => { + this.map?.zoomIn(); + }; + + private onZoomOut = () => { + this.map?.zoomOut(); + }; + render() { return ( bodyId={this.getBodyId()} markerId={this.getMarkerId()} error={this.state.error} + zoomButtons={true} + onZoomIn={this.onZoomIn} + onZoomOut={this.onZoomOut} /> ); diff --git a/src/components/views/messages/MLocationBody.tsx b/src/components/views/messages/MLocationBody.tsx index 689de44233..bce5c85022 100644 --- a/src/components/views/messages/MLocationBody.tsx +++ b/src/components/views/messages/MLocationBody.tsx @@ -29,6 +29,7 @@ import Modal from '../../../Modal'; import LocationViewDialog from '../location/LocationViewDialog'; import TooltipTarget from '../elements/TooltipTarget'; import { Alignment } from '../elements/Tooltip'; +import AccessibleButton from '../elements/AccessibleButton'; interface IState { error: Error; @@ -89,7 +90,7 @@ export default class MLocationBody extends React.Component { ); }; - render() { + render(): React.ReactElement { return ) => void; + zoomButtons?: boolean; + onZoomIn?: () => void; + onZoomOut?: () => void; } -export function LocationBodyContent(props: ILocationBodyContentProps) { +export function LocationBodyContent(props: ILocationBodyContentProps): + React.ReactElement { const mapDiv =
+ { + props.zoomButtons + ? + : null + } + ; +} + +interface IZoomButtonsProps { + onZoomIn: () => void; + onZoomOut: () => void; +} + +function ZoomButtons(props: IZoomButtonsProps): React.ReactElement { + return
+ +
+ + +
+
; } diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index c51d290db1..dcf06bec6d 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -2093,6 +2093,8 @@ "You sent a verification request": "You sent a verification request", "Expand map": "Expand map", "Failed to load map": "Failed to load map", + "Zoom in": "Zoom in", + "Zoom out": "Zoom out", "Vote not registered": "Vote not registered", "Sorry, your vote was not registered. Please try again.": "Sorry, your vote was not registered. Please try again.", "Final result based on %(count)s votes|other": "Final result based on %(count)s votes", @@ -2201,8 +2203,6 @@ "%(count)s members including %(commaSeparatedMembers)s|one": "%(commaSeparatedMembers)s", "%(count)s people you know have already joined|other": "%(count)s people you know have already joined", "%(count)s people you know have already joined|one": "%(count)s person you know has already joined", - "Zoom out": "Zoom out", - "Zoom in": "Zoom in", "Rotate Left": "Rotate Left", "Rotate Right": "Rotate Right", "Information": "Information",