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

Commit 176e49e

Browse files
author
Kerry
authored
enable geolocation behaviour in location picker for live share type (#8068)
* enable geolocation behaviour in location picker for live share type Signed-off-by: Kerry Archibald <[email protected]> * add empty lines Signed-off-by: Kerry Archibald <[email protected]>
1 parent 9f6c238 commit 176e49e

File tree

5 files changed

+81
-68
lines changed

5 files changed

+81
-68
lines changed

res/css/components/views/location/_ShareType.scss

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,7 @@ limitations under the License.
8484
border-radius: 50%;
8585

8686
&.Own {
87-
// color is set by user color class
88-
// generated from id
89-
border-color: currentColor;
87+
border-color: $accent;
9088
}
9189

9290
&.Live {

res/css/views/location/_LocationPicker.scss

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@ limitations under the License.
6262
width: 31px;
6363
height: 31px;
6464
border-radius: 50%;
65-
background-color: $accent;
6665
filter: drop-shadow(0px 3px 5px rgba(0, 0, 0, 0.2));
66+
background-color: currentColor;
6767

6868
display: flex;
6969
align-items: center;
@@ -87,7 +87,7 @@ limitations under the License.
8787
width: 9px;
8888
height: 5px;
8989
position: absolute;
90-
background-color: $accent;
90+
background-color: currentColor;
9191
}
9292
}
9393
}
@@ -135,3 +135,11 @@ limitations under the License.
135135
width: 100%;
136136
height: 48px;
137137
}
138+
139+
// live marker color is set by user color class
140+
// generated from userid
141+
// others are $accent
142+
.mx_MLocationBody_marker-Self,
143+
.mx_MLocationBody_marker-Pin {
144+
color: $accent;
145+
}

src/components/views/location/LocationPicker.tsx

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import maplibregl, { MapMouseEvent } from 'maplibre-gl';
1919
import { logger } from "matrix-js-sdk/src/logger";
2020
import { RoomMember } from 'matrix-js-sdk/src/models/room-member';
2121
import { ClientEvent, IClientWellKnown } from 'matrix-js-sdk/src/client';
22+
import classNames from 'classnames';
2223

2324
import { _t } from '../../../languageHandler';
2425
import { replaceableComponent } from "../../../utils/replaceableComponent";
@@ -33,6 +34,7 @@ import { Icon as LocationIcon } from '../../../../res/img/element-icons/location
3334
import { LocationShareError } from './LocationShareErrors';
3435
import AccessibleButton from '../elements/AccessibleButton';
3536
import { MapError } from './MapError';
37+
import { getUserNameColorClass } from '../../../utils/FormattingUtils';
3638
export interface ILocationPickerProps {
3739
sender: RoomMember;
3840
shareType: LocationShareType;
@@ -52,13 +54,8 @@ interface IState {
5254
error?: LocationShareError;
5355
}
5456

55-
/*
56-
* An older version of this file allowed manually picking a location on
57-
* the map to share, instead of sharing your current location.
58-
* Since the current designs do not cover this case, it was removed from
59-
* the code but you should be able to find it in the git history by
60-
* searching for the commit that remove manualPosition from this file.
61-
*/
57+
const isSharingOwnLocation = (shareType: LocationShareType): boolean =>
58+
shareType === LocationShareType.Own || shareType === LocationShareType.Live;
6259

6360
@replaceableComponent("views.location.LocationPicker")
6461
class LocationPicker extends React.Component<ILocationPickerProps, IState> {
@@ -117,7 +114,7 @@ class LocationPicker extends React.Component<ILocationPickerProps, IState> {
117114

118115
this.geolocate.on('error', this.onGeolocateError);
119116

120-
if (this.props.shareType === LocationShareType.Own) {
117+
if (isSharingOwnLocation(this.props.shareType)) {
121118
this.geolocate.on('geolocate', this.onGeolocate);
122119
}
123120

@@ -191,7 +188,7 @@ class LocationPicker extends React.Component<ILocationPickerProps, IState> {
191188
logger.error("Could not fetch location", e);
192189
// close the dialog and show an error when trying to share own location
193190
// pin drop location without permissions is ok
194-
if (this.props.shareType === LocationShareType.Own) {
191+
if (isSharingOwnLocation(this.props.shareType)) {
195192
this.props.onFinished();
196193
Modal.createTrackedDialog(
197194
'Could not fetch location',
@@ -225,6 +222,8 @@ class LocationPicker extends React.Component<ILocationPickerProps, IState> {
225222
</div>;
226223
}
227224

225+
const userColorClass = getUserNameColorClass(this.props.sender.userId);
226+
228227
return (
229228
<div className="mx_LocationPicker">
230229
<div id="mx_LocationPicker_map" />
@@ -249,9 +248,14 @@ class LocationPicker extends React.Component<ILocationPickerProps, IState> {
249248
</AccessibleButton>
250249
</form>
251250
</div>
252-
<div className="mx_MLocationBody_marker" id={this.getMarkerId()}>
251+
<div className={classNames(
252+
"mx_MLocationBody_marker",
253+
`mx_MLocationBody_marker-${this.props.shareType}`,
254+
userColorClass,
255+
)}
256+
id={this.getMarkerId()}>
253257
<div className="mx_MLocationBody_markerBorder">
254-
{ this.props.shareType === LocationShareType.Own ?
258+
{ isSharingOwnLocation(this.props.shareType) ?
255259
<MemberAvatar
256260
member={this.props.sender}
257261
width={27}

src/components/views/location/ShareType.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import React, { HTMLAttributes, useContext } from 'react';
1919
import MatrixClientContext from '../../../contexts/MatrixClientContext';
2020
import { _t } from '../../../languageHandler';
2121
import { OwnProfileStore } from '../../../stores/OwnProfileStore';
22-
import { getUserNameColorClass } from '../../../utils/FormattingUtils';
2322
import BaseAvatar from '../avatars/BaseAvatar';
2423
import AccessibleButton from '../elements/AccessibleButton';
2524
import Heading from '../typography/Heading';
@@ -34,9 +33,8 @@ const UserAvatar = () => {
3433
// 40 - 2px border
3534
const avatarSize = 36;
3635
const avatarUrl = OwnProfileStore.instance.getHttpAvatarUrl(avatarSize);
37-
const colorClass = getUserNameColorClass(userId);
3836

39-
return <div className={`mx_ShareType_option-icon ${LocationShareType.Own} ${colorClass}`}>
37+
return <div className={`mx_ShareType_option-icon ${LocationShareType.Own}`}>
4038
<BaseAvatar
4139
idName={userId}
4240
name={displayName}

test/components/views/location/LocationPicker-test.tsx

Lines changed: 54 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -205,61 +205,66 @@ describe("LocationPicker", () => {
205205
expect(mockGeolocate.trigger).toHaveBeenCalled();
206206
});
207207

208-
describe('for Own location share type', () => {
209-
it('closes and displays error when geolocation errors', () => {
210-
// suppress expected error log
211-
jest.spyOn(logger, 'error').mockImplementation(() => { });
212-
const onFinished = jest.fn();
213-
getComponent({ onFinished });
214-
215-
expect(mockMap.addControl).toHaveBeenCalledWith(mockGeolocate);
216-
act(() => {
217-
// @ts-ignore
218-
mockMap.emit('load');
219-
// @ts-ignore
220-
mockGeolocate.emit('error', {});
208+
const testUserLocationShareTypes = (shareType: LocationShareType.Own | LocationShareType.Live) => {
209+
describe(`for ${shareType} location share type`, () => {
210+
it('closes and displays error when geolocation errors', () => {
211+
// suppress expected error log
212+
jest.spyOn(logger, 'error').mockImplementation(() => { });
213+
const onFinished = jest.fn();
214+
getComponent({ onFinished, shareType });
215+
216+
expect(mockMap.addControl).toHaveBeenCalledWith(mockGeolocate);
217+
act(() => {
218+
// @ts-ignore
219+
mockMap.emit('load');
220+
// @ts-ignore
221+
mockGeolocate.emit('error', {});
222+
});
223+
224+
// dialog is closed on error
225+
expect(onFinished).toHaveBeenCalled();
221226
});
222227

223-
// dialog is closed on error
224-
expect(onFinished).toHaveBeenCalled();
225-
});
226-
227-
it('sets position on geolocate event', () => {
228-
const wrapper = getComponent();
229-
act(() => {
230-
// @ts-ignore
231-
mocked(mockGeolocate).emit('geolocate', mockGeolocationPosition);
232-
wrapper.setProps({});
228+
it('sets position on geolocate event', () => {
229+
const wrapper = getComponent({ shareType });
230+
act(() => {
231+
// @ts-ignore
232+
mocked(mockGeolocate).emit('geolocate', mockGeolocationPosition);
233+
wrapper.setProps({});
234+
});
235+
236+
// marker added
237+
expect(maplibregl.Marker).toHaveBeenCalled();
238+
expect(mockMarker.setLngLat).toHaveBeenCalledWith(new maplibregl.LngLat(
239+
12.4, 43.2,
240+
));
241+
// submit button is enabled when position is truthy
242+
expect(findByTestId(wrapper, 'location-picker-submit-button').at(0).props().disabled).toBeFalsy();
243+
expect(wrapper.find('MemberAvatar').length).toBeTruthy();
233244
});
234245

235-
// marker added
236-
expect(maplibregl.Marker).toHaveBeenCalled();
237-
expect(mockMarker.setLngLat).toHaveBeenCalledWith(new maplibregl.LngLat(
238-
12.4, 43.2,
239-
));
240-
// submit button is enabled when position is truthy
241-
expect(findByTestId(wrapper, 'location-picker-submit-button').at(0).props().disabled).toBeFalsy();
242-
expect(wrapper.find('MemberAvatar').length).toBeTruthy();
243-
});
244-
245-
it('submits location', () => {
246-
const onChoose = jest.fn();
247-
const wrapper = getComponent({ onChoose });
248-
act(() => {
249-
// @ts-ignore
250-
mocked(mockGeolocate).emit('geolocate', mockGeolocationPosition);
251-
// make sure button is enabled
252-
wrapper.setProps({});
246+
it('submits location', () => {
247+
const onChoose = jest.fn();
248+
const wrapper = getComponent({ onChoose, shareType });
249+
act(() => {
250+
// @ts-ignore
251+
mocked(mockGeolocate).emit('geolocate', mockGeolocationPosition);
252+
// make sure button is enabled
253+
wrapper.setProps({});
254+
});
255+
256+
act(() => {
257+
findByTestId(wrapper, 'location-picker-submit-button').at(0).simulate('click');
258+
});
259+
260+
// content of this call is tested in LocationShareMenu-test
261+
expect(onChoose).toHaveBeenCalled();
253262
});
254-
255-
act(() => {
256-
findByTestId(wrapper, 'location-picker-submit-button').at(0).simulate('click');
257-
});
258-
259-
// content of this call is tested in LocationShareMenu-test
260-
expect(onChoose).toHaveBeenCalled();
261263
});
262-
});
264+
};
265+
266+
testUserLocationShareTypes(LocationShareType.Own);
267+
testUserLocationShareTypes(LocationShareType.Live);
263268

264269
describe('for Pin drop location share type', () => {
265270
const shareType = LocationShareType.Pin;

0 commit comments

Comments
 (0)