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

Commit e97536e

Browse files
author
Kerry
authored
Live location sharing - refresh beacon timers on tab becoming active (#8515)
* add visibilitychange listener Signed-off-by: Kerry Archibald <[email protected]> * test Signed-off-by: Kerry Archibald <[email protected]> * restore event listener mock Signed-off-by: Kerry Archibald <[email protected]>
1 parent 2c19d28 commit e97536e

File tree

2 files changed

+46
-2
lines changed

2 files changed

+46
-2
lines changed

src/components/views/beacon/LeftPanelLiveShareWarning.tsx

+23-2
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ limitations under the License.
1515
*/
1616

1717
import classNames from 'classnames';
18-
import React from 'react';
19-
import { BeaconIdentifier, Room } from 'matrix-js-sdk/src/matrix';
18+
import React, { useEffect } from 'react';
19+
import { Beacon, BeaconIdentifier, Room } from 'matrix-js-sdk/src/matrix';
2020

2121
import { useEventEmitterState } from '../../../hooks/useEventEmitter';
2222
import { _t } from '../../../languageHandler';
@@ -61,6 +61,25 @@ const getLabel = (hasStoppingErrors: boolean, hasLocationErrors: boolean): strin
6161
return _t('You are sharing your live location');
6262
};
6363

64+
const useLivenessMonitor = (liveBeaconIds: BeaconIdentifier[], beacons: Map<BeaconIdentifier, Beacon>): void => {
65+
useEffect(() => {
66+
// chromium sets the minimum timer interval to 1000ms
67+
// for inactive tabs
68+
// refresh beacon monitors when the tab becomes active again
69+
const onPageVisibilityChanged = () => {
70+
if (document.visibilityState === 'visible') {
71+
liveBeaconIds.map(identifier => beacons.get(identifier)?.monitorLiveness());
72+
}
73+
};
74+
if (liveBeaconIds.length) {
75+
document.addEventListener("visibilitychange", onPageVisibilityChanged);
76+
}
77+
() => {
78+
document.removeEventListener("visibilitychange", onPageVisibilityChanged);
79+
};
80+
}, [liveBeaconIds, beacons]);
81+
};
82+
6483
const LeftPanelLiveShareWarning: React.FC<Props> = ({ isMinimized }) => {
6584
const isMonitoringLiveLocation = useEventEmitterState(
6685
OwnBeaconStore.instance,
@@ -91,6 +110,8 @@ const LeftPanelLiveShareWarning: React.FC<Props> = ({ isMinimized }) => {
91110
const hasLocationPublishErrors = !!beaconIdsWithLocationPublishError.length;
92111
const hasStoppingErrors = !!beaconIdsWithStoppingError.length;
93112

113+
useLivenessMonitor(liveBeaconIds, OwnBeaconStore.instance.beacons);
114+
94115
if (!isMonitoringLiveLocation) {
95116
return null;
96117
}

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

+23
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ jest.mock('../../../../src/stores/OwnBeaconStore', () => {
3434
public getBeaconById = jest.fn();
3535
public getLiveBeaconIds = jest.fn().mockReturnValue([]);
3636
public readonly beaconUpdateErrors = new Map<BeaconIdentifier, Error>();
37+
public readonly beacons = new Map<BeaconIdentifier, Beacon>();
3738
}
3839
return {
3940
// @ts-ignore
@@ -103,6 +104,10 @@ describe('<LeftPanelLiveShareWarning />', () => {
103104
mocked(OwnBeaconStore.instance).getLiveBeaconIds.mockReturnValue([beacon2.identifier, beacon1.identifier]);
104105
});
105106

107+
afterAll(() => {
108+
jest.spyOn(document, 'addEventListener').mockRestore();
109+
});
110+
106111
it('renders correctly when not minimized', () => {
107112
const component = getComponent();
108113
expect(component).toMatchSnapshot();
@@ -195,6 +200,24 @@ describe('<LeftPanelLiveShareWarning />', () => {
195200
expect(component.html()).toBe(null);
196201
});
197202

203+
it('refreshes beacon liveness monitors when pagevisibilty changes to visible', () => {
204+
OwnBeaconStore.instance.beacons.set(beacon1.identifier, beacon1);
205+
OwnBeaconStore.instance.beacons.set(beacon2.identifier, beacon2);
206+
const beacon1MonitorSpy = jest.spyOn(beacon1, 'monitorLiveness');
207+
const beacon2MonitorSpy = jest.spyOn(beacon1, 'monitorLiveness');
208+
209+
jest.spyOn(document, 'addEventListener').mockImplementation(
210+
(_e, listener) => (listener as EventListener)(new Event('')),
211+
);
212+
213+
expect(beacon1MonitorSpy).not.toHaveBeenCalled();
214+
215+
getComponent();
216+
217+
expect(beacon1MonitorSpy).toHaveBeenCalled();
218+
expect(beacon2MonitorSpy).toHaveBeenCalled();
219+
});
220+
198221
describe('stopping errors', () => {
199222
it('renders stopping error', () => {
200223
OwnBeaconStore.instance.beaconUpdateErrors.set(beacon2.identifier, new Error('error'));

0 commit comments

Comments
 (0)