Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Commit

Permalink
Live location sharing - extract location markers into generic Marker (#…
Browse files Browse the repository at this point in the history
…8225)

* extract location markers into generic Marker

Signed-off-by: Kerry Archibald <[email protected]>

* comments

Signed-off-by: Kerry Archibald <[email protected]>

* remove skinned

Signed-off-by: Kerry Archibald <[email protected]>
  • Loading branch information
Kerry authored Apr 6, 2022
1 parent b9da225 commit b987390
Show file tree
Hide file tree
Showing 10 changed files with 188 additions and 145 deletions.
1 change: 1 addition & 0 deletions res/css/_components.scss
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
@import "./components/views/location/_LiveDurationDropdown.scss";
@import "./components/views/location/_LocationShareMenu.scss";
@import "./components/views/location/_MapError.scss";
@import "./components/views/location/_Marker.scss";
@import "./components/views/location/_ShareDialogButtons.scss";
@import "./components/views/location/_ShareType.scss";
@import "./components/views/spaces/_QuickThemeSwitcher.scss";
Expand Down
46 changes: 46 additions & 0 deletions res/css/components/views/location/_Marker.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
Copyright 2022 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_Marker_defaultColor {
color: $accent;
}

.mx_Marker_border {
width: 42px;
height: 42px;
border-radius: 50%;
filter: drop-shadow(0px 3px 5px rgba(0, 0, 0, 0.2));
background-color: currentColor;

display: flex;
justify-content: center;
align-items: center;

// caret down
&::before {
content: '';
border-left: 5px solid transparent;
border-right: 5px solid transparent;
border-top: 5px solid currentColor;
position: absolute;
bottom: -4px;
}
}

.mx_Marker_icon {
color: white;
height: 20px;
}
46 changes: 0 additions & 46 deletions res/css/views/location/_LocationPicker.scss
Original file line number Diff line number Diff line change
Expand Up @@ -55,39 +55,6 @@ limitations under the License.
.maplibregl-user-location-dot {
display: none;
}

.mx_MLocationBody_markerBorder {
width: 31px;
height: 31px;
border-radius: 50%;
filter: drop-shadow(0px 3px 5px rgba(0, 0, 0, 0.2));
background-color: currentColor;

display: flex;
align-items: center;
justify-content: center;
}

.mx_MLocationBody_pointer {
position: absolute;
bottom: -3px;
left: 11px;
width: 9px;
height: 5px;

&::before {
mask-image: url('$(res)/img/location/pointer.svg');
mask-position: center;
mask-repeat: no-repeat;
mask-size: 9px;
content: '';
display: inline-block;
width: 9px;
height: 5px;
position: absolute;
background-color: currentColor;
}
}
}

.mx_LocationPicker_footer {
Expand All @@ -106,11 +73,6 @@ limitations under the License.
}
}

.mx_MLocationBody_markerIcon {
color: white;
height: 20px;
}

.mx_LocationPicker_pinText {
position: absolute;
top: $spacing-16;
Expand All @@ -135,11 +97,3 @@ limitations under the License.
width: 100%;
height: 48px;
}

// live marker color is set by user color class
// generated from userid
// others are $accent
.mx_MLocationBody_marker-Self,
.mx_MLocationBody_marker-Pin {
color: $accent;
}
50 changes: 0 additions & 50 deletions res/css/views/messages/_MLocationBody.scss
Original file line number Diff line number Diff line change
Expand Up @@ -22,56 +22,6 @@ limitations under the License.

border-radius: $timeline-image-border-radius;
}

.mx_MLocationBody_markerBorder {
width: 31px;
height: 31px;
border-radius: 50%;
filter: drop-shadow(0px 3px 5px rgba(0, 0, 0, 0.2));
background-color: $accent;

// See _LocationPicker.scss
display: flex;
justify-content: center;
align-items: center;

.mx_BaseAvatar {
margin: 0;
line-height: 1;
}
}

.mx_MLocationBody_pointer {
position: absolute;
bottom: -3px;
left: 11px;
width: 9px;
height: 5px;

&::before {
mask-image: url('$(res)/img/location/pointer.svg');
mask-position: center;
mask-repeat: no-repeat;
mask-size: 9px;
content: '';
display: inline-block;
width: 9px;
height: 5px;
position: absolute;
background-color: $accent;
}
}

.mx_MLocationBody_markerContents {
background-color: $location-marker-color;
margin: 0;
width: 31px;
height: 31px;
mask-repeat: no-repeat;
mask-size: 16px;
mask-position: center;
mask-image: url('$(res)/img/element-icons/location.svg');
}
}

/* In the timeline, we fit the width of the container */
Expand Down
36 changes: 7 additions & 29 deletions src/components/views/location/LocationPicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,20 @@ import maplibregl, { MapMouseEvent } from 'maplibre-gl';
import { logger } from "matrix-js-sdk/src/logger";
import { RoomMember } from 'matrix-js-sdk/src/models/room-member';
import { ClientEvent, IClientWellKnown } from 'matrix-js-sdk/src/client';
import classNames from 'classnames';

import { Icon as LocationIcon } from '../../../../res/img/element-icons/location.svg';
import { _t } from '../../../languageHandler';
import MatrixClientContext from '../../../contexts/MatrixClientContext';
import Modal from '../../../Modal';
import SdkConfig from '../../../SdkConfig';
import { tileServerFromWellKnown } from '../../../utils/WellKnownUtils';
import { getUserNameColorClass } from '../../../utils/FormattingUtils';
import { GenericPosition, genericPositionFromGeolocation, getGeoUri } from '../../../utils/beacon';
import { LocationShareError, findMapStyleUrl } from '../../../utils/location';
import MemberAvatar from '../avatars/MemberAvatar';
import ErrorDialog from '../dialogs/ErrorDialog';
import AccessibleButton from '../elements/AccessibleButton';
import { MapError } from './MapError';
import LiveDurationDropdown, { DEFAULT_DURATION_MS } from './LiveDurationDropdown';
import { LocationShareType, ShareLocationFn } from './shareLocation';
import Marker from './Marker';

export interface ILocationPickerProps {
sender: RoomMember;
Expand Down Expand Up @@ -225,8 +222,6 @@ class LocationPicker extends React.Component<ILocationPickerProps, IState> {
</div>;
}

const userColorClass = getUserNameColorClass(this.props.sender.userId);

return (
<div className="mx_LocationPicker">
<div id="mx_LocationPicker_map" />
Expand Down Expand Up @@ -256,13 +251,7 @@ class LocationPicker extends React.Component<ILocationPickerProps, IState> {
</AccessibleButton>
</form>
</div>
<div className={classNames(
"mx_MLocationBody_marker",
`mx_MLocationBody_marker-${this.props.shareType}`,
userColorClass,
)}
id={this.getMarkerId()}
>
<div id={this.getMarkerId()}>
{ /*
maplibregl hijacks the div above to style the marker
it must be in the dom when the map is initialised
Expand All @@ -271,22 +260,11 @@ class LocationPicker extends React.Component<ILocationPickerProps, IState> {
so hide the internal visible elements
*/ }

{ !!this.marker && <>
<div className="mx_MLocationBody_markerBorder">
{ isSharingOwnLocation(this.props.shareType) ?
<MemberAvatar
member={this.props.sender}
width={27}
height={27}
viewUserOnClick={false}
/>
: <LocationIcon className="mx_MLocationBody_markerIcon" />
}
</div>
<div
className="mx_MLocationBody_pointer"
/>
</> }
{ !!this.marker && <Marker
roomMember={isSharingOwnLocation(this.props.shareType) ? this.props.sender : undefined}
useMemberColor={this.props.shareType === LocationShareType.Live}
/>
}
</div>
</div>
);
Expand Down
58 changes: 58 additions & 0 deletions src/components/views/location/Marker.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
Copyright 2022 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 classNames from 'classnames';
import { RoomMember } from 'matrix-js-sdk/src/matrix';

import { Icon as LocationIcon } from '../../../../res/img/element-icons/location.svg';
import { getUserNameColorClass } from '../../../utils/FormattingUtils';
import MemberAvatar from '../avatars/MemberAvatar';

interface Props {
id?: string;
// renders MemberAvatar when provided
roomMember?: RoomMember;
// use member text color as background
useMemberColor?: boolean;
}

/**
* Generic location marker
*/
const Marker: React.FC<Props> = ({ id, roomMember, useMemberColor }) => {
const memberColorClass = useMemberColor && roomMember ? getUserNameColorClass(roomMember.userId) : '';
return <div
id={id}
className={classNames("mx_Marker", memberColorClass, {
"mx_Marker_defaultColor": !memberColorClass,
})}
>
<div className="mx_Marker_border">
{ roomMember ?
<MemberAvatar
member={roomMember}
width={36}
height={36}
viewUserOnClick={false}
/>
: <LocationIcon className="mx_Marker_icon" />
}
</div>
</div>;
};

export default Marker;
23 changes: 4 additions & 19 deletions src/components/views/messages/MLocationBody.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import { ClientEvent, IClientWellKnown } from 'matrix-js-sdk/src/client';

import { IBodyProps } from "./IBodyProps";
import { _t } from '../../../languageHandler';
import MemberAvatar from '../avatars/MemberAvatar';
import Modal from '../../../Modal';
import {
parseGeoUri,
Expand All @@ -41,6 +40,7 @@ import { Alignment } from '../elements/Tooltip';
import AccessibleButton from '../elements/AccessibleButton';
import { tileServerFromWellKnown } from '../../../utils/WellKnownUtils';
import MatrixClientContext from '../../../contexts/MatrixClientContext';
import Marker from '../location/Marker';

interface IState {
error: Error;
Expand Down Expand Up @@ -175,16 +175,8 @@ export function LocationBodyContent(props: ILocationBodyContentProps):
className="mx_MLocationBody_map"
/>;

const markerContents = (
isSelfLocation(props.mxEvent.getContent())
? <MemberAvatar
member={props.mxEvent.sender}
width={27}
height={27}
viewUserOnClick={false}
/>
: <div className="mx_MLocationBody_markerContents" />
);
// only pass member to marker when should render avatar marker
const markerRoomMember = isSelfLocation(props.mxEvent.getContent()) ? props.mxEvent.sender : undefined;

return <div className="mx_MLocationBody">
{
Expand All @@ -198,14 +190,7 @@ export function LocationBodyContent(props: ILocationBodyContentProps):
</TooltipTarget>
: mapDiv
}
<div className="mx_MLocationBody_marker" id={props.markerId}>
<div className="mx_MLocationBody_markerBorder">
{ markerContents }
</div>
<div
className="mx_MLocationBody_pointer"
/>
</div>
<Marker id={props.markerId} roomMember={markerRoomMember} />
{
props.zoomButtons
? <ZoomButtons
Expand Down
2 changes: 1 addition & 1 deletion test/components/views/location/LocationPicker-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ describe("LocationPicker", () => {
));

// marker is set, icon not avatar
expect(wrapper.find('.mx_MLocationBody_markerIcon').length).toBeTruthy();
expect(wrapper.find('.mx_Marker_icon').length).toBeTruthy();
});

it('submits location', () => {
Expand Down
Loading

0 comments on commit b987390

Please sign in to comment.