diff --git a/res/css/components/views/location/_ShareType.scss b/res/css/components/views/location/_ShareType.scss index ba21a7caa0d..bf50ca7fde6 100644 --- a/res/css/components/views/location/_ShareType.scss +++ b/res/css/components/views/location/_ShareType.scss @@ -84,9 +84,7 @@ limitations under the License. border-radius: 50%; &.Own { - // color is set by user color class - // generated from id - border-color: currentColor; + border-color: $accent; } &.Live { diff --git a/res/css/views/location/_LocationPicker.scss b/res/css/views/location/_LocationPicker.scss index 53b3655ed8b..0b2555abf6a 100644 --- a/res/css/views/location/_LocationPicker.scss +++ b/res/css/views/location/_LocationPicker.scss @@ -62,8 +62,8 @@ limitations under the License. width: 31px; height: 31px; border-radius: 50%; - background-color: $accent; filter: drop-shadow(0px 3px 5px rgba(0, 0, 0, 0.2)); + background-color: currentColor; display: flex; align-items: center; @@ -87,7 +87,7 @@ limitations under the License. width: 9px; height: 5px; position: absolute; - background-color: $accent; + background-color: currentColor; } } } @@ -135,3 +135,11 @@ 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; +} diff --git a/src/components/views/location/LocationPicker.tsx b/src/components/views/location/LocationPicker.tsx index 26eda1edba5..f9c1c0eb6f2 100644 --- a/src/components/views/location/LocationPicker.tsx +++ b/src/components/views/location/LocationPicker.tsx @@ -19,6 +19,7 @@ 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 { _t } from '../../../languageHandler'; import { replaceableComponent } from "../../../utils/replaceableComponent"; @@ -33,6 +34,7 @@ import { Icon as LocationIcon } from '../../../../res/img/element-icons/location import { LocationShareError } from './LocationShareErrors'; import AccessibleButton from '../elements/AccessibleButton'; import { MapError } from './MapError'; +import { getUserNameColorClass } from '../../../utils/FormattingUtils'; export interface ILocationPickerProps { sender: RoomMember; shareType: LocationShareType; @@ -52,13 +54,8 @@ interface IState { error?: LocationShareError; } -/* - * An older version of this file allowed manually picking a location on - * the map to share, instead of sharing your current location. - * Since the current designs do not cover this case, it was removed from - * the code but you should be able to find it in the git history by - * searching for the commit that remove manualPosition from this file. - */ +const isSharingOwnLocation = (shareType: LocationShareType): boolean => + shareType === LocationShareType.Own || shareType === LocationShareType.Live; @replaceableComponent("views.location.LocationPicker") class LocationPicker extends React.Component { @@ -117,7 +114,7 @@ class LocationPicker extends React.Component { this.geolocate.on('error', this.onGeolocateError); - if (this.props.shareType === LocationShareType.Own) { + if (isSharingOwnLocation(this.props.shareType)) { this.geolocate.on('geolocate', this.onGeolocate); } @@ -191,7 +188,7 @@ class LocationPicker extends React.Component { logger.error("Could not fetch location", e); // close the dialog and show an error when trying to share own location // pin drop location without permissions is ok - if (this.props.shareType === LocationShareType.Own) { + if (isSharingOwnLocation(this.props.shareType)) { this.props.onFinished(); Modal.createTrackedDialog( 'Could not fetch location', @@ -225,6 +222,8 @@ class LocationPicker extends React.Component { ; } + const userColorClass = getUserNameColorClass(this.props.sender.userId); + return (
@@ -249,9 +248,14 @@ class LocationPicker extends React.Component {
-
+
- { this.props.shareType === LocationShareType.Own ? + { isSharingOwnLocation(this.props.shareType) ? { // 40 - 2px border const avatarSize = 36; const avatarUrl = OwnProfileStore.instance.getHttpAvatarUrl(avatarSize); - const colorClass = getUserNameColorClass(userId); - return
+ return
{ expect(mockGeolocate.trigger).toHaveBeenCalled(); }); - describe('for Own location share type', () => { - it('closes and displays error when geolocation errors', () => { - // suppress expected error log - jest.spyOn(logger, 'error').mockImplementation(() => { }); - const onFinished = jest.fn(); - getComponent({ onFinished }); - - expect(mockMap.addControl).toHaveBeenCalledWith(mockGeolocate); - act(() => { - // @ts-ignore - mockMap.emit('load'); - // @ts-ignore - mockGeolocate.emit('error', {}); + const testUserLocationShareTypes = (shareType: LocationShareType.Own | LocationShareType.Live) => { + describe(`for ${shareType} location share type`, () => { + it('closes and displays error when geolocation errors', () => { + // suppress expected error log + jest.spyOn(logger, 'error').mockImplementation(() => { }); + const onFinished = jest.fn(); + getComponent({ onFinished, shareType }); + + expect(mockMap.addControl).toHaveBeenCalledWith(mockGeolocate); + act(() => { + // @ts-ignore + mockMap.emit('load'); + // @ts-ignore + mockGeolocate.emit('error', {}); + }); + + // dialog is closed on error + expect(onFinished).toHaveBeenCalled(); }); - // dialog is closed on error - expect(onFinished).toHaveBeenCalled(); - }); - - it('sets position on geolocate event', () => { - const wrapper = getComponent(); - act(() => { - // @ts-ignore - mocked(mockGeolocate).emit('geolocate', mockGeolocationPosition); - wrapper.setProps({}); + it('sets position on geolocate event', () => { + const wrapper = getComponent({ shareType }); + act(() => { + // @ts-ignore + mocked(mockGeolocate).emit('geolocate', mockGeolocationPosition); + wrapper.setProps({}); + }); + + // marker added + expect(maplibregl.Marker).toHaveBeenCalled(); + expect(mockMarker.setLngLat).toHaveBeenCalledWith(new maplibregl.LngLat( + 12.4, 43.2, + )); + // submit button is enabled when position is truthy + expect(findByTestId(wrapper, 'location-picker-submit-button').at(0).props().disabled).toBeFalsy(); + expect(wrapper.find('MemberAvatar').length).toBeTruthy(); }); - // marker added - expect(maplibregl.Marker).toHaveBeenCalled(); - expect(mockMarker.setLngLat).toHaveBeenCalledWith(new maplibregl.LngLat( - 12.4, 43.2, - )); - // submit button is enabled when position is truthy - expect(findByTestId(wrapper, 'location-picker-submit-button').at(0).props().disabled).toBeFalsy(); - expect(wrapper.find('MemberAvatar').length).toBeTruthy(); - }); - - it('submits location', () => { - const onChoose = jest.fn(); - const wrapper = getComponent({ onChoose }); - act(() => { - // @ts-ignore - mocked(mockGeolocate).emit('geolocate', mockGeolocationPosition); - // make sure button is enabled - wrapper.setProps({}); + it('submits location', () => { + const onChoose = jest.fn(); + const wrapper = getComponent({ onChoose, shareType }); + act(() => { + // @ts-ignore + mocked(mockGeolocate).emit('geolocate', mockGeolocationPosition); + // make sure button is enabled + wrapper.setProps({}); + }); + + act(() => { + findByTestId(wrapper, 'location-picker-submit-button').at(0).simulate('click'); + }); + + // content of this call is tested in LocationShareMenu-test + expect(onChoose).toHaveBeenCalled(); }); - - act(() => { - findByTestId(wrapper, 'location-picker-submit-button').at(0).simulate('click'); - }); - - // content of this call is tested in LocationShareMenu-test - expect(onChoose).toHaveBeenCalled(); }); - }); + }; + + testUserLocationShareTypes(LocationShareType.Own); + testUserLocationShareTypes(LocationShareType.Live); describe('for Pin drop location share type', () => { const shareType = LocationShareType.Pin;