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

Live location sharing - refresh beacon timers on tab becoming active #8515

Merged
merged 3 commits into from
May 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 23 additions & 2 deletions src/components/views/beacon/LeftPanelLiveShareWarning.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ limitations under the License.
*/

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

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

const useLivenessMonitor = (liveBeaconIds: BeaconIdentifier[], beacons: Map<BeaconIdentifier, Beacon>): void => {
useEffect(() => {
// chromium sets the minimum timer interval to 1000ms
// for inactive tabs
// refresh beacon monitors when the tab becomes active again
const onPageVisibilityChanged = () => {
if (document.visibilityState === 'visible') {
liveBeaconIds.map(identifier => beacons.get(identifier)?.monitorLiveness());
}
};
if (liveBeaconIds.length) {
document.addEventListener("visibilitychange", onPageVisibilityChanged);
}
() => {
document.removeEventListener("visibilitychange", onPageVisibilityChanged);
};
}, [liveBeaconIds, beacons]);
};

const LeftPanelLiveShareWarning: React.FC<Props> = ({ isMinimized }) => {
const isMonitoringLiveLocation = useEventEmitterState(
OwnBeaconStore.instance,
Expand Down Expand Up @@ -91,6 +110,8 @@ const LeftPanelLiveShareWarning: React.FC<Props> = ({ isMinimized }) => {
const hasLocationPublishErrors = !!beaconIdsWithLocationPublishError.length;
const hasStoppingErrors = !!beaconIdsWithStoppingError.length;

useLivenessMonitor(liveBeaconIds, OwnBeaconStore.instance.beacons);

if (!isMonitoringLiveLocation) {
return null;
}
Expand Down
23 changes: 23 additions & 0 deletions test/components/views/beacon/LeftPanelLiveShareWarning-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ jest.mock('../../../../src/stores/OwnBeaconStore', () => {
public getBeaconById = jest.fn();
public getLiveBeaconIds = jest.fn().mockReturnValue([]);
public readonly beaconUpdateErrors = new Map<BeaconIdentifier, Error>();
public readonly beacons = new Map<BeaconIdentifier, Beacon>();
}
return {
// @ts-ignore
Expand Down Expand Up @@ -103,6 +104,10 @@ describe('<LeftPanelLiveShareWarning />', () => {
mocked(OwnBeaconStore.instance).getLiveBeaconIds.mockReturnValue([beacon2.identifier, beacon1.identifier]);
});

afterAll(() => {
jest.spyOn(document, 'addEventListener').mockRestore();
});

it('renders correctly when not minimized', () => {
const component = getComponent();
expect(component).toMatchSnapshot();
Expand Down Expand Up @@ -195,6 +200,24 @@ describe('<LeftPanelLiveShareWarning />', () => {
expect(component.html()).toBe(null);
});

it('refreshes beacon liveness monitors when pagevisibilty changes to visible', () => {
OwnBeaconStore.instance.beacons.set(beacon1.identifier, beacon1);
OwnBeaconStore.instance.beacons.set(beacon2.identifier, beacon2);
const beacon1MonitorSpy = jest.spyOn(beacon1, 'monitorLiveness');
const beacon2MonitorSpy = jest.spyOn(beacon1, 'monitorLiveness');

jest.spyOn(document, 'addEventListener').mockImplementation(
(_e, listener) => (listener as EventListener)(new Event('')),
);

expect(beacon1MonitorSpy).not.toHaveBeenCalled();

getComponent();

expect(beacon1MonitorSpy).toHaveBeenCalled();
expect(beacon2MonitorSpy).toHaveBeenCalled();
});

describe('stopping errors', () => {
it('renders stopping error', () => {
OwnBeaconStore.instance.beaconUpdateErrors.set(beacon2.identifier, new Error('error'));
Expand Down