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

Commit 399ac61

Browse files
author
Kerry
authored
LLS: fix jumpy maximised map (#8387)
* add maxzoom to map fit bounds Signed-off-by: Kerry Archibald <[email protected]> * take snapshot of bounds at center on dialog open Signed-off-by: Kerry Archibald <[email protected]>
1 parent 86419b1 commit 399ac61

File tree

4 files changed

+46
-6
lines changed

4 files changed

+46
-6
lines changed

src/components/views/beacon/BeaconViewDialog.tsx

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
1616

17-
import React, { useState } from 'react';
17+
import React, { useState, useRef } from 'react';
1818
import { MatrixClient } from 'matrix-js-sdk/src/client';
1919
import {
2020
Beacon,
@@ -56,6 +56,17 @@ const getBoundsCenter = (bounds: Bounds): string | undefined => {
5656
});
5757
};
5858

59+
const useInitialMapPosition = (liveBeacons: Beacon[], focusBeacon?: Beacon): {
60+
bounds?: Bounds; centerGeoUri: string;
61+
} => {
62+
const bounds = useRef<Bounds | undefined>(getBeaconBounds(liveBeacons));
63+
const centerGeoUri = useRef<string>(
64+
focusBeacon?.latestLocationState?.uri ||
65+
getBoundsCenter(bounds.current),
66+
);
67+
return { bounds: bounds.current, centerGeoUri: centerGeoUri.current };
68+
};
69+
5970
/**
6071
* Dialog to view live beacons maximised
6172
*/
@@ -69,8 +80,7 @@ const BeaconViewDialog: React.FC<IProps> = ({
6980

7081
const [isSidebarOpen, setSidebarOpen] = useState(false);
7182

72-
const bounds = getBeaconBounds(liveBeacons);
73-
const centerGeoUri = focusBeacon?.latestLocationState?.uri || getBoundsCenter(bounds);
83+
const { bounds, centerGeoUri } = useInitialMapPosition(liveBeacons, focusBeacon);
7484

7585
return (
7686
<BaseDialog
@@ -79,7 +89,7 @@ const BeaconViewDialog: React.FC<IProps> = ({
7989
fixedWidth={false}
8090
>
8191
<MatrixClientContext.Provider value={matrixClient}>
82-
{ !!bounds ? <Map
92+
{ !!liveBeacons?.length ? <Map
8393
id='mx_BeaconViewDialog'
8494
bounds={bounds}
8595
centerGeoUri={centerGeoUri}

src/components/views/location/Map.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ const useMapWithStyle = ({ id, centerGeoUri, onError, interactive, bounds }) =>
6464
[bounds.west, bounds.south],
6565
[bounds.east, bounds.north],
6666
);
67-
map.fitBounds(lngLatBounds, { padding: 100 });
67+
map.fitBounds(lngLatBounds, { padding: 100, maxZoom: 15 });
6868
} catch (error) {
6969
logger.error('Invalid map bounds', error);
7070
}

test/components/views/beacon/BeaconViewDialog-test.tsx

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import {
2424
RoomMember,
2525
getBeaconInfoIdentifier,
2626
} from 'matrix-js-sdk/src/matrix';
27+
import maplibregl from 'maplibre-gl';
2728

2829
import BeaconViewDialog from '../../../../src/components/views/beacon/BeaconViewDialog';
2930
import {
@@ -58,6 +59,8 @@ describe('<BeaconViewDialog />', () => {
5859
getVisibleRooms: jest.fn().mockReturnValue([]),
5960
});
6061

62+
const mockMap = new maplibregl.Map();
63+
6164
// make fresh rooms every time
6265
// as we update room state
6366
const setupRoom = (stateEvents: MatrixEvent[] = []): Room => {
@@ -88,6 +91,8 @@ describe('<BeaconViewDialog />', () => {
8891

8992
beforeEach(() => {
9093
jest.spyOn(OwnBeaconStore.instance, 'getLiveBeaconIds').mockRestore();
94+
95+
jest.clearAllMocks();
9196
});
9297

9398
it('renders a map with markers', () => {
@@ -151,6 +156,31 @@ describe('<BeaconViewDialog />', () => {
151156
expect(component.find('BeaconMarker').length).toEqual(2);
152157
});
153158

159+
it('does not update bounds or center on changing beacons', () => {
160+
const room = setupRoom([defaultEvent]);
161+
const beacon = room.currentState.beacons.get(getBeaconInfoIdentifier(defaultEvent));
162+
beacon.addLocations([location1]);
163+
const component = getComponent();
164+
expect(component.find('BeaconMarker').length).toEqual(1);
165+
166+
const anotherBeaconEvent = makeBeaconInfoEvent(bobId,
167+
roomId,
168+
{ isLive: true },
169+
'$bob-room1-1',
170+
);
171+
172+
act(() => {
173+
// emits RoomStateEvent.BeaconLiveness
174+
room.currentState.setStateEvents([anotherBeaconEvent]);
175+
});
176+
177+
component.setProps({});
178+
179+
// two markers now!
180+
expect(mockMap.setCenter).toHaveBeenCalledTimes(1);
181+
expect(mockMap.fitBounds).toHaveBeenCalledTimes(1);
182+
});
183+
154184
it('renders a fallback when no live beacons remain', () => {
155185
const onFinished = jest.fn();
156186
const room = setupRoom([defaultEvent]);

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ describe('<Map />', () => {
125125
const bounds = { north: 51, south: 50, east: 42, west: 41 };
126126
getComponent({ bounds });
127127
expect(mockMap.fitBounds).toHaveBeenCalledWith(new maplibregl.LngLatBounds([bounds.west, bounds.south],
128-
[bounds.east, bounds.north]), { padding: 100 });
128+
[bounds.east, bounds.north]), { padding: 100, maxZoom: 15 });
129129
});
130130

131131
it('handles invalid bounds', () => {

0 commit comments

Comments
 (0)