Skip to content
This repository was archived by the owner on Sep 11, 2024. It is now read-only.
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
1 change: 1 addition & 0 deletions res/css/_components.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
@import "./_font-sizes.scss";
@import "./_font-weights.scss";
@import "./_spacing.scss";
@import "./components/views/beacon/_BeaconStatus.scss";
@import "./components/views/beacon/_LeftPanelLiveShareWarning.scss";
@import "./components/views/beacon/_LiveTimeRemaining.scss";
@import "./components/views/beacon/_RoomLiveShareWarning.scss";
Expand Down
60 changes: 60 additions & 0 deletions res/css/components/views/beacon/_BeaconStatus.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
Copyright 2022 The Matrix.org Foundation C.I.C.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

.mx_BeaconStatus {
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;

box-sizing: border-box;
padding: $spacing-8;

color: var(--color);
font-size: $font-12px;
}

.mx_BeaconStatus_Loading,
.mx_BeaconStatus_Stopped {
--color: $tertiary-content;
}

.mx_BeaconStatus_Active,
.mx_BeaconStatus_Error {
--color: $primary-content;
}

.mx_BeaconStatus_icon {
height: 32px;
width: 32px;

flex: 0 0 32px;
margin-right: $spacing-8;
}

.mx_BeaconStatus_activeDescription {
flex: 1;
display: flex;
flex-direction: column;
line-height: $font-14px;
}

.mx_BeaconStatus_stopButton {
// override button link_inline styles
color: $alert !important;
font-weight: $font-semi-bold !important;
text-transform: uppercase;
}
4 changes: 4 additions & 0 deletions res/css/components/views/beacon/_RoomLiveShareWarning.scss
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ limitations under the License.
margin-left: $spacing-16;
}

.mx_RoomLiveShareWarning_stopButton {
margin-left: $spacing-16;
}

.mx_RoomLiveShareWarning_closeButtonIcon {
height: $font-18px;
padding: $spacing-4;
Expand Down
5 changes: 5 additions & 0 deletions res/css/components/views/beacon/_StyledLiveBeaconIcon.scss
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,8 @@ limitations under the License.
background-color: $alert;
border-color: $alert;
}

.mx_StyledLiveBeaconIcon.mx_StyledLiveBeaconIcon_idle {
background-color: $quaternary-content;
border-color: $quaternary-content;
}
7 changes: 7 additions & 0 deletions res/css/components/views/messages/_MBeaconBody.scss
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,13 @@ limitations under the License.
color: $quaternary-content;
}

.mx_MBeaconBody_chin {
position: absolute;
bottom: 0;
width: 100%;
background-color: $overlay-background;
}

.mx_EventTile[data-layout="bubble"] .mx_EventTile_line .mx_MBeaconBody {
max-width: 100%;
width: 450px;
Expand Down
1 change: 1 addition & 0 deletions res/themes/dark/css/_dark.scss
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ $quinary-content: #394049;

$system: #21262C;
$background: #15191E;
$overlay-background: rgba($background, 0.85);

$panel-base: #8D97A5; // This color is not intended for use in the app
$panels: rgba($system, 0.9);
Expand Down
2 changes: 2 additions & 0 deletions res/themes/legacy-dark/css/_legacy-dark.scss
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ $quaternary-content: #6F7882;
$quinary-content: $quaternary-content;
$system: #21262C;
$background: $primary-bg-color;
$overlay-background: rgba($background, 0.85);

$panels: rgba($system, 0.9);
$panel-base: #8D97A5; // This color is not intended for use in the app
$panel-selected: rgba($panel-base, 0.3);
Expand Down
2 changes: 2 additions & 0 deletions res/themes/legacy-light/css/_legacy-light.scss
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,8 @@ $quaternary-content: #6F7882;
$quinary-content: $quaternary-content;
$system: #F4F6FA;
$background: $primary-bg-color;
$overlay-background: rgba($background, 0.85);

$panels: rgba($system, 0.9);
$panel-base: #8D97A5; // This color is not intended for use in the app
$panel-selected: rgba($tertiary-content, 0.3);
Expand Down
1 change: 1 addition & 0 deletions res/themes/light/css/_light.scss
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ $quinary-content: #E3E8F0;

$system: #F4F6FA;
$background: #ffffff;
$overlay-background: rgba($background, 0.85);

$panels: rgba($system, 0.9);
$panel-selected: rgba($tertiary-content, 0.3);
Expand Down
71 changes: 71 additions & 0 deletions src/components/views/beacon/BeaconStatus.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
Copyright 2022 The Matrix.org Foundation C.I.C.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

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

import StyledLiveBeaconIcon from './StyledLiveBeaconIcon';
import { _t } from '../../../languageHandler';
import AccessibleButton from '../elements/AccessibleButton';
import LiveTimeRemaining from './LiveTimeRemaining';
import { BeaconDisplayStatus } from './displayStatus';

interface Props {
displayStatus: BeaconDisplayStatus;
beacon?: Beacon;
label?: string;
// assumes permission to stop was checked by parent
stopBeacon?: () => void;
}

const BeaconStatus: React.FC<Props & HTMLProps<HTMLDivElement>> =
({ beacon, displayStatus, label, stopBeacon, className, ...rest }) => {
const isIdle = displayStatus === BeaconDisplayStatus.Loading ||
displayStatus === BeaconDisplayStatus.Stopped;

return <div
{...rest}
className={classNames('mx_BeaconStatus', `mx_BeaconStatus_${displayStatus}`, className)}
>
<StyledLiveBeaconIcon
className='mx_BeaconStatus_icon'
withError={displayStatus === BeaconDisplayStatus.Error}
isIdle={isIdle}
/>
{ displayStatus === BeaconDisplayStatus.Loading && <span>{ _t('Loading live location...') }</span> }
{ displayStatus === BeaconDisplayStatus.Stopped && <span>{ _t('Live location ended') }</span> }

{ /* TODO error */ }

{ displayStatus === BeaconDisplayStatus.Active && beacon && <>
<div className='mx_BeaconStatus_activeDescription'>
{ label }
<LiveTimeRemaining beacon={beacon} />
</div>
{ stopBeacon && <AccessibleButton
data-test-id='beacon-status-stop-beacon'
kind='link'
onClick={stopBeacon}
className='mx_BeaconStatus_stopButton'
>{ _t('Stop') }</AccessibleButton>
}
</>
}
</div>;
};

export default BeaconStatus;
75 changes: 5 additions & 70 deletions src/components/views/beacon/RoomLiveShareWarning.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,86 +14,20 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

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

import { _t } from '../../../languageHandler';
import { useEventEmitterState } from '../../../hooks/useEventEmitter';
import { OwnBeaconStore, OwnBeaconStoreEvent } from '../../../stores/OwnBeaconStore';
import { sortBeaconsByLatestExpiry } from '../../../utils/beacon';
import { useOwnLiveBeacons } from '../../../utils/beacon';
import AccessibleButton 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';

/**
* It's technically possible to have multiple live beacons in one room
* Select the latest expiry to display,
* and kill all beacons on stop sharing
*/
type LiveBeaconsState = {
beacon?: Beacon;
onStopSharing?: () => void;
onResetWireError?: () => void;
stoppingInProgress?: boolean;
hasStopSharingError?: boolean;
hasWireError?: boolean;
};
const useLiveBeacons = (liveBeaconIds: BeaconIdentifier[], roomId: string): LiveBeaconsState => {
const [stoppingInProgress, setStoppingInProgress] = useState(false);
const [error, setError] = useState<Error>();

const hasWireError = useEventEmitterState(
OwnBeaconStore.instance,
OwnBeaconStoreEvent.WireError,
() =>
OwnBeaconStore.instance.hasWireErrors(roomId),
);

// reset stopping in progress on change in live ids
useEffect(() => {
setStoppingInProgress(false);
setError(undefined);
}, [liveBeaconIds]);

// select the beacon with latest expiry to display expiry time
const beacon = liveBeaconIds.map(beaconId => OwnBeaconStore.instance.getBeaconById(beaconId))
.sort(sortBeaconsByLatestExpiry)
.shift();

const onStopSharing = async () => {
setStoppingInProgress(true);
try {
await Promise.all(liveBeaconIds.map(beaconId => OwnBeaconStore.instance.stopBeacon(beaconId)));
} catch (error) {
// only clear loading in case of error
// to avoid flash of not-loading state
// after beacons have been stopped but we wait for sync
setError(error);
setStoppingInProgress(false);
}
};

const onResetWireError = () => {
liveBeaconIds.map(beaconId => OwnBeaconStore.instance.resetWireError(beaconId));
};

return {
onStopSharing,
onResetWireError,
beacon,
stoppingInProgress,
hasWireError,
hasStopSharingError: !!error,
};
};

const getLabel = (hasWireError: boolean, hasStopSharingError: boolean): string => {
if (hasWireError) {
return _t('An error occured whilst sharing your live location, please try again');
Expand All @@ -116,7 +50,7 @@ const RoomLiveShareWarningInner: React.FC<RoomLiveShareWarningInnerProps> = ({ l
stoppingInProgress,
hasStopSharingError,
hasWireError,
} = useLiveBeacons(liveBeaconIds, roomId);
} = useOwnLiveBeacons(liveBeaconIds);

if (!beacon) {
return null;
Expand Down Expand Up @@ -147,6 +81,7 @@ const RoomLiveShareWarningInner: React.FC<RoomLiveShareWarningInnerProps> = ({ l
{ !stoppingInProgress && !hasError && <LiveTimeRemaining beacon={beacon} /> }

<AccessibleButton
className='mx_RoomLiveShareWarning_stopButton'
data-test-id='room-live-share-primary-button'
onClick={onButtonClick}
kind='danger'
Expand Down
12 changes: 10 additions & 2 deletions src/components/views/beacon/StyledLiveBeaconIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,19 @@ import { Icon as LiveLocationIcon } from '../../../../res/img/location/live-loca
interface Props extends React.SVGProps<SVGSVGElement> {
// use error styling when true
withError?: boolean;
isIdle?: boolean;
}
const StyledLiveBeaconIcon: React.FC<Props> = ({ className, withError, ...props }) =>
const StyledLiveBeaconIcon: React.FC<Props> = ({ className, withError, isIdle, ...props }) =>
<LiveLocationIcon
{...props}
className={classNames('mx_StyledLiveBeaconIcon', className, { 'mx_StyledLiveBeaconIcon_error': withError })}
className={classNames(
'mx_StyledLiveBeaconIcon',
className,
{
'mx_StyledLiveBeaconIcon_error': withError,
'mx_StyledLiveBeaconIcon_idle': isIdle,

})}
/>;

export default StyledLiveBeaconIcon;
9 changes: 9 additions & 0 deletions src/components/views/messages/MBeaconBody.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ import { BeaconDisplayStatus, getBeaconDisplayStatus } from '../beacon/displaySt
import Spinner from '../elements/Spinner';
import Map from '../location/Map';
import SmartMarker from '../location/SmartMarker';
import BeaconStatus from '../beacon/BeaconStatus';
import { IBodyProps } from "./IBodyProps";
import { _t } from '../../../languageHandler';

const useBeaconState = (beaconInfoEvent: MatrixEvent): {
beacon?: Beacon;
Expand Down Expand Up @@ -76,6 +78,7 @@ const useUniqueId = (eventId: string): string => {

const MBeaconBody: React.FC<IBodyProps> = React.forwardRef(({ mxEvent }, ref) => {
const {
beacon,
isLive,
latestLocationState,
} = useBeaconState(mxEvent);
Expand Down Expand Up @@ -113,6 +116,12 @@ const MBeaconBody: React.FC<IBodyProps> = React.forwardRef(({ mxEvent }, ref) =>
}
</div>
}
<BeaconStatus
className='mx_MBeaconBody_chin'
beacon={beacon}
displayStatus={displayStatus}
label={_t('View live location')}
/>
</div>
);
});
Expand Down
3 changes: 3 additions & 0 deletions src/i18n/strings/en_EN.json
Original file line number Diff line number Diff line change
Expand Up @@ -2079,6 +2079,7 @@
"Pick a date to jump to": "Pick a date to jump to",
"Go": "Go",
"Error processing audio message": "Error processing audio message",
"View live location": "View live location",
"React": "React",
"Reply in thread": "Reply in thread",
"Can't create a thread from an event with an existing relation": "Can't create a thread from an event with an existing relation",
Expand Down Expand Up @@ -2900,6 +2901,8 @@
"Beta": "Beta",
"Leave the beta": "Leave the beta",
"Join the beta": "Join the beta",
"Loading live location...": "Loading live location...",
"Live location ended": "Live location ended",
"An error occured whilst sharing your live location": "An error occured whilst sharing your live location",
"You are sharing your live location": "You are sharing your live location",
"%(timeRemaining)s left": "%(timeRemaining)s left",
Expand Down
1 change: 1 addition & 0 deletions src/utils/beacon/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ limitations under the License.
export * from './duration';
export * from './geolocation';
export * from './useBeacon';
export * from './useOwnLiveBeacons';
Loading