Live location share - link to timeline tile from share warning (PSF-1078) (#8752)
* navigate to live location tile from left panel live warning Signed-off-by: Kerry Archibald <kerrya@element.io> * navigate to beacon tile from room live share warning Signed-off-by: Kerry Archibald <kerrya@element.io> * add cursor Signed-off-by: Kerry Archibald <kerrya@element.io>
This commit is contained in:
parent
f65e8d088e
commit
56b0b79fb7
6 changed files with 67 additions and 11 deletions
|
@ -26,6 +26,7 @@ limitations under the License.
|
|||
|
||||
color: $primary-content;
|
||||
background-color: $system;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mx_RoomLiveShareWarning_icon {
|
||||
|
|
|
@ -16,7 +16,7 @@ limitations under the License.
|
|||
|
||||
import classNames from 'classnames';
|
||||
import React, { useEffect } from 'react';
|
||||
import { Beacon, BeaconIdentifier, Room } from 'matrix-js-sdk/src/matrix';
|
||||
import { Beacon, BeaconIdentifier } from 'matrix-js-sdk/src/matrix';
|
||||
|
||||
import { useEventEmitterState } from '../../../hooks/useEventEmitter';
|
||||
import { _t } from '../../../languageHandler';
|
||||
|
@ -33,13 +33,12 @@ interface Props {
|
|||
|
||||
/**
|
||||
* Choose the most relevant beacon
|
||||
* and get its roomId
|
||||
*/
|
||||
const chooseBestBeaconRoomId = (
|
||||
const chooseBestBeacon = (
|
||||
liveBeaconIds: BeaconIdentifier[],
|
||||
updateErrorBeaconIds: BeaconIdentifier[],
|
||||
locationErrorBeaconIds: BeaconIdentifier[],
|
||||
): Room['roomId'] | undefined => {
|
||||
): Beacon | undefined => {
|
||||
// both lists are ordered by creation timestamp in store
|
||||
// so select latest beacon
|
||||
const beaconId = updateErrorBeaconIds?.[0] ?? locationErrorBeaconIds?.[0] ?? liveBeaconIds?.[0];
|
||||
|
@ -48,7 +47,7 @@ const chooseBestBeaconRoomId = (
|
|||
}
|
||||
const beacon = OwnBeaconStore.instance.getBeaconById(beaconId);
|
||||
|
||||
return beacon?.roomId;
|
||||
return beacon;
|
||||
};
|
||||
|
||||
const getLabel = (hasStoppingErrors: boolean, hasLocationErrors: boolean): string => {
|
||||
|
@ -116,15 +115,18 @@ const LeftPanelLiveShareWarning: React.FC<Props> = ({ isMinimized }) => {
|
|||
return null;
|
||||
}
|
||||
|
||||
const relevantBeaconRoomId = chooseBestBeaconRoomId(
|
||||
const relevantBeacon = chooseBestBeacon(
|
||||
liveBeaconIds, beaconIdsWithStoppingError, beaconIdsWithLocationPublishError,
|
||||
);
|
||||
|
||||
const onWarningClick = relevantBeaconRoomId ? () => {
|
||||
const onWarningClick = relevantBeacon ? () => {
|
||||
dispatcher.dispatch<ViewRoomPayload>({
|
||||
action: Action.ViewRoom,
|
||||
room_id: relevantBeaconRoomId,
|
||||
room_id: relevantBeacon.roomId,
|
||||
metricsTrigger: undefined,
|
||||
event_id: relevantBeacon.beaconInfoId,
|
||||
scroll_into_view: true,
|
||||
highlighted: true,
|
||||
});
|
||||
} : undefined;
|
||||
|
||||
|
|
|
@ -21,11 +21,14 @@ import { _t } from '../../../languageHandler';
|
|||
import { useEventEmitterState } from '../../../hooks/useEventEmitter';
|
||||
import { OwnBeaconStore, OwnBeaconStoreEvent } from '../../../stores/OwnBeaconStore';
|
||||
import { useOwnLiveBeacons } from '../../../utils/beacon';
|
||||
import AccessibleButton from '../elements/AccessibleButton';
|
||||
import AccessibleButton, { ButtonEvent } from '../elements/AccessibleButton';
|
||||
import Spinner from '../elements/Spinner';
|
||||
import StyledLiveBeaconIcon from './StyledLiveBeaconIcon';
|
||||
import { Icon as CloseIcon } from '../../../../res/img/image-view/close.svg';
|
||||
import LiveTimeRemaining from './LiveTimeRemaining';
|
||||
import dispatcher from '../../../dispatcher/dispatcher';
|
||||
import { ViewRoomPayload } from '../../../dispatcher/payloads/ViewRoomPayload';
|
||||
import { Action } from '../../../dispatcher/actions';
|
||||
|
||||
const getLabel = (hasLocationPublishError: boolean, hasStopSharingError: boolean): string => {
|
||||
if (hasLocationPublishError) {
|
||||
|
@ -57,6 +60,13 @@ const RoomLiveShareWarningInner: React.FC<RoomLiveShareWarningInnerProps> = ({ l
|
|||
|
||||
const hasError = hasStopSharingError || hasLocationPublishError;
|
||||
|
||||
// eat events from buttons so navigate to tile
|
||||
// is not triggered
|
||||
const stopPropagationWrapper = (callback: () => void) => (e?: ButtonEvent) => {
|
||||
e?.stopPropagation();
|
||||
callback();
|
||||
};
|
||||
|
||||
const onButtonClick = () => {
|
||||
if (hasLocationPublishError) {
|
||||
onResetLocationPublishError();
|
||||
|
@ -65,8 +75,20 @@ const RoomLiveShareWarningInner: React.FC<RoomLiveShareWarningInnerProps> = ({ l
|
|||
}
|
||||
};
|
||||
|
||||
const onClick = () => {
|
||||
dispatcher.dispatch<ViewRoomPayload>({
|
||||
action: Action.ViewRoom,
|
||||
room_id: beacon.roomId,
|
||||
metricsTrigger: undefined,
|
||||
event_id: beacon.beaconInfoId,
|
||||
scroll_into_view: true,
|
||||
highlighted: true,
|
||||
});
|
||||
};
|
||||
|
||||
return <div
|
||||
className='mx_RoomLiveShareWarning'
|
||||
onClick={onClick}
|
||||
>
|
||||
<StyledLiveBeaconIcon className="mx_RoomLiveShareWarning_icon" withError={hasError} />
|
||||
|
||||
|
@ -82,7 +104,7 @@ const RoomLiveShareWarningInner: React.FC<RoomLiveShareWarningInnerProps> = ({ l
|
|||
<AccessibleButton
|
||||
className='mx_RoomLiveShareWarning_stopButton'
|
||||
data-test-id='room-live-share-primary-button'
|
||||
onClick={onButtonClick}
|
||||
onClick={stopPropagationWrapper(onButtonClick)}
|
||||
kind='danger'
|
||||
element='button'
|
||||
disabled={stoppingInProgress}
|
||||
|
@ -94,7 +116,7 @@ const RoomLiveShareWarningInner: React.FC<RoomLiveShareWarningInnerProps> = ({ l
|
|||
title={_t('Stop sharing and close')}
|
||||
element='button'
|
||||
className='mx_RoomLiveShareWarning_closeButton'
|
||||
onClick={onStopSharing}
|
||||
onClick={stopPropagationWrapper(onStopSharing)}
|
||||
>
|
||||
<CloseIcon className='mx_RoomLiveShareWarning_closeButtonIcon' />
|
||||
</AccessibleButton> }
|
||||
|
|
|
@ -126,6 +126,9 @@ describe('<LeftPanelLiveShareWarning />', () => {
|
|||
metricsTrigger: undefined,
|
||||
// latest beacon's room
|
||||
room_id: roomId2,
|
||||
event_id: beacon2.beaconInfoId,
|
||||
highlighted: true,
|
||||
scroll_into_view: true,
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -158,6 +161,9 @@ describe('<LeftPanelLiveShareWarning />', () => {
|
|||
metricsTrigger: undefined,
|
||||
// error beacon's room
|
||||
room_id: roomId1,
|
||||
event_id: beacon1.beaconInfoId,
|
||||
highlighted: true,
|
||||
scroll_into_view: true,
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -264,6 +270,9 @@ describe('<LeftPanelLiveShareWarning />', () => {
|
|||
metricsTrigger: undefined,
|
||||
// stopping error beacon's room
|
||||
room_id: beacon2.roomId,
|
||||
event_id: beacon2.beaconInfoId,
|
||||
highlighted: true,
|
||||
scroll_into_view: true,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -32,6 +32,8 @@ import {
|
|||
resetAsyncStoreWithClient,
|
||||
setupAsyncStoreWithClient,
|
||||
} from '../../../test-utils';
|
||||
import defaultDispatcher from '../../../../src/dispatcher/dispatcher';
|
||||
import { Action } from '../../../../src/dispatcher/actions';
|
||||
|
||||
jest.useFakeTimers();
|
||||
describe('<RoomLiveShareWarning />', () => {
|
||||
|
@ -117,6 +119,7 @@ describe('<RoomLiveShareWarning />', () => {
|
|||
afterAll(() => {
|
||||
jest.spyOn(global.Date, 'now').mockRestore();
|
||||
localStorageSpy.mockRestore();
|
||||
jest.spyOn(defaultDispatcher, 'dispatch').mockRestore();
|
||||
});
|
||||
|
||||
const getExpiryText = wrapper => findByTestId(wrapper, 'room-live-share-expiry').text();
|
||||
|
@ -263,6 +266,24 @@ describe('<RoomLiveShareWarning />', () => {
|
|||
expect(clearIntervalSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('navigates to beacon tile on click', () => {
|
||||
const dispatcherSpy = jest.spyOn(defaultDispatcher, 'dispatch');
|
||||
const component = getComponent({ roomId: room1Id });
|
||||
|
||||
act(() => {
|
||||
component.simulate('click');
|
||||
});
|
||||
|
||||
expect(dispatcherSpy).toHaveBeenCalledWith({
|
||||
action: Action.ViewRoom,
|
||||
event_id: room1Beacon1.getId(),
|
||||
room_id: room1Id,
|
||||
highlighted: true,
|
||||
scroll_into_view: true,
|
||||
metricsTrigger: undefined,
|
||||
});
|
||||
});
|
||||
|
||||
describe('stopping beacons', () => {
|
||||
it('stops beacon on stop sharing click', () => {
|
||||
const component = getComponent({ roomId: room2Id });
|
||||
|
|
|
@ -20,6 +20,7 @@ exports[`<RoomLiveShareWarning /> when user has live beacons and geolocation is
|
|||
>
|
||||
<div
|
||||
className="mx_RoomLiveShareWarning"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<StyledLiveBeaconIcon
|
||||
className="mx_RoomLiveShareWarning_icon"
|
||||
|
|
Loading…
Reference in a new issue