Live location sharing - basic maximised beacon map (#8310)

* open a dialog with map centered around first beacon

Signed-off-by: Kerry Archibald <kerrya@element.io>

* add room member markers

Signed-off-by: Kerry Archibald <kerrya@element.io>

* fix unmount issue in smart marker

Signed-off-by: Kerry Archibald <kerrya@element.io>

* dont throw on no more live locations

Signed-off-by: Kerry Archibald <kerrya@element.io>

* cursor on beacon maps

Signed-off-by: Kerry Archibald <kerrya@element.io>

* fussy import ordering

Signed-off-by: Kerry Archibald <kerrya@element.io>

* test dialog opening from beacon body

Signed-off-by: Kerry Archibald <kerrya@element.io>

* test beaconmarker

Signed-off-by: Kerry Archibald <kerrya@element.io>

* test BeaconViewDialog

Signed-off-by: Kerry Archibald <kerrya@element.io>

* comment

Signed-off-by: Kerry Archibald <kerrya@element.io>

* use unstable prefix for wk tile_Server

Signed-off-by: Kerry Archibald <kerrya@element.io>

* unstable prefix for new m.tile_server use in test

Signed-off-by: Kerry Archibald <kerrya@element.io>
This commit is contained in:
Kerry 2022-04-14 15:14:05 +02:00 committed by GitHub
parent 1c215e2b71
commit f95106d2c6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 894 additions and 56 deletions

View file

@ -29,6 +29,8 @@ import { getMockClientWithEventEmitter, makeBeaconEvent, makeBeaconInfoEvent } f
import { RoomPermalinkCreator } from '../../../../src/utils/permalinks/Permalinks';
import { MediaEventHelper } from '../../../../src/utils/MediaEventHelper';
import MatrixClientContext from '../../../../src/contexts/MatrixClientContext';
import Modal from '../../../../src/Modal';
import { TILE_SERVER_WK_KEY } from '../../../../src/utils/WellKnownUtils';
describe('<MBeaconBody />', () => {
// 14.03.2022 16:15
@ -43,7 +45,7 @@ describe('<MBeaconBody />', () => {
const mockClient = getMockClientWithEventEmitter({
getClientWellKnown: jest.fn().mockReturnValue({
"m.tile_server": { map_style_url: 'maps.com' },
[TILE_SERVER_WK_KEY.name]: { map_style_url: 'maps.com' },
}),
getUserId: jest.fn().mockReturnValue(aliceId),
getRoom: jest.fn(),
@ -83,6 +85,8 @@ describe('<MBeaconBody />', () => {
wrappingComponentProps: { value: mockClient },
});
const modalSpy = jest.spyOn(Modal, 'createTrackedDialog').mockReturnValue(undefined);
beforeEach(() => {
jest.clearAllMocks();
});
@ -110,6 +114,23 @@ describe('<MBeaconBody />', () => {
expect(component.text()).toEqual("Live location ended");
});
it('does not open maximised map when on click when beacon is stopped', () => {
const beaconInfoEvent = makeBeaconInfoEvent(aliceId,
roomId,
// puts this beacons live period in the past
{ isLive: true, timestamp: now - 600000, timeout: 500 },
'$alice-room1-1',
);
makeRoomWithStateEvents([beaconInfoEvent]);
const component = getComponent({ mxEvent: beaconInfoEvent });
act(() => {
component.find('.mx_MBeaconBody_map').simulate('click');
});
expect(modalSpy).not.toHaveBeenCalled();
});
it('renders stopped UI when a beacon event is not the latest beacon for a user', () => {
const aliceBeaconInfo1 = makeBeaconInfoEvent(
aliceId,
@ -213,6 +234,40 @@ describe('<MBeaconBody />', () => {
expect(component.text()).toEqual("Loading live location...");
});
it('does nothing on click when a beacon has no location', () => {
makeRoomWithStateEvents([aliceBeaconInfo]);
const component = getComponent({ mxEvent: aliceBeaconInfo });
act(() => {
component.find('.mx_MBeaconBody_map').simulate('click');
});
expect(modalSpy).not.toHaveBeenCalled();
});
it('renders a live beacon with a location correctly', () => {
const room = makeRoomWithStateEvents([aliceBeaconInfo]);
const beaconInstance = room.currentState.beacons.get(getBeaconInfoIdentifier(aliceBeaconInfo));
beaconInstance.addLocations([location1]);
const component = getComponent({ mxEvent: aliceBeaconInfo });
expect(component.find('Map').length).toBeTruthy;
});
it('opens maximised map view on click when beacon has a live location', () => {
const room = makeRoomWithStateEvents([aliceBeaconInfo]);
const beaconInstance = room.currentState.beacons.get(getBeaconInfoIdentifier(aliceBeaconInfo));
beaconInstance.addLocations([location1]);
const component = getComponent({ mxEvent: aliceBeaconInfo });
act(() => {
component.find('Map').simulate('click');
});
// opens modal
expect(modalSpy).toHaveBeenCalled();
});
it('updates latest location', () => {
const room = makeRoomWithStateEvents([aliceBeaconInfo]);
const component = getComponent({ mxEvent: aliceBeaconInfo });

View file

@ -28,6 +28,7 @@ import { RoomPermalinkCreator } from "../../../../src/utils/permalinks/Permalink
import { MediaEventHelper } from "../../../../src/utils/MediaEventHelper";
import Modal from '../../../../src/Modal';
import SdkConfig from "../../../../src/SdkConfig";
import { TILE_SERVER_WK_KEY } from '../../../../src/utils/WellKnownUtils';
import { makeLocationEvent } from "../../../test-utils/location";
import { getMockClientWithEventEmitter } from '../../../test-utils';
@ -37,7 +38,7 @@ describe("MLocationBody", () => {
const userId = '@user:server';
const mockClient = getMockClientWithEventEmitter({
getClientWellKnown: jest.fn().mockReturnValue({
"m.tile_server": { map_style_url: 'maps.com' },
[TILE_SERVER_WK_KEY.name]: { map_style_url: 'maps.com' },
}),
isGuest: jest.fn().mockReturnValue(false),
});
@ -78,7 +79,7 @@ describe("MLocationBody", () => {
it('displays correct fallback content when map_style_url is misconfigured', () => {
const mockMap = new maplibregl.Map();
mockClient.getClientWellKnown.mockReturnValue({
"m.tile_server": { map_style_url: 'bad-tile-server.com' },
[TILE_SERVER_WK_KEY.name]: { map_style_url: 'bad-tile-server.com' },
});
const component = getComponent();
@ -93,7 +94,7 @@ describe("MLocationBody", () => {
describe('without error', () => {
beforeEach(() => {
mockClient.getClientWellKnown.mockReturnValue({
"m.tile_server": { map_style_url: 'maps.com' },
[TILE_SERVER_WK_KEY.name]: { map_style_url: 'maps.com' },
});
// MLocationBody uses random number for map id

View file

@ -158,22 +158,24 @@ exports[`MLocationBody <MLocationBody> without error renders map correctly 1`] =
}
}
>
<ForwardRef
id="mx_MLocationBody_$2_1f9acffa-marker"
>
<div
className="mx_Marker mx_Marker_defaultColor"
<span>
<ForwardRef
id="mx_MLocationBody_$2_1f9acffa-marker"
>
<div
className="mx_Marker_border"
className="mx_Marker mx_Marker_defaultColor"
id="mx_MLocationBody_$2_1f9acffa-marker"
>
<div
className="mx_Marker_icon"
/>
className="mx_Marker_border"
>
<div
className="mx_Marker_icon"
/>
</div>
</div>
</div>
</ForwardRef>
</ForwardRef>
</span>
</SmartMarker>
</div>
</Map>