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

Commit 324c96a

Browse files
committed
Merge branch 'develop' into video-room-lobby
2 parents 2147f82 + 4a38cbd commit 324c96a

34 files changed

+792
-61
lines changed

res/css/_common.scss

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -692,3 +692,9 @@ legend {
692692
}
693693
}
694694
}
695+
696+
@define-mixin ListResetDefault {
697+
list-style: none;
698+
padding: 0;
699+
margin: 0;
700+
}

res/css/_components.scss

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44
@import "./_font-sizes.scss";
55
@import "./_font-weights.scss";
66
@import "./_spacing.scss";
7+
@import "./components/views/beacon/_BeaconListItem.scss";
78
@import "./components/views/beacon/_BeaconStatus.scss";
89
@import "./components/views/beacon/_BeaconViewDialog.scss";
10+
@import "./components/views/beacon/_DialogSidebar.scss";
911
@import "./components/views/beacon/_LeftPanelLiveShareWarning.scss";
1012
@import "./components/views/beacon/_LiveTimeRemaining.scss";
1113
@import "./components/views/beacon/_OwnBeaconStatus.scss";
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
Copyright 2022 The Matrix.org Foundation C.I.C.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
.mx_BeaconListItem {
18+
box-sizing: border-box;
19+
display: flex;
20+
flex-direction: row;
21+
align-items: flex-start;
22+
padding: $spacing-12 0;
23+
24+
border-bottom: 1px solid $system;
25+
}
26+
27+
.mx_BeaconListItem_avatarIcon {
28+
flex: 0 0;
29+
height: 32px;
30+
width: 32px;
31+
}
32+
33+
.mx_BeaconListItem_avatar {
34+
flex: 0 0;
35+
box-sizing: border-box;
36+
37+
margin-right: $spacing-8;
38+
border: 2px solid $location-live-color;
39+
}
40+
41+
.mx_BeaconListItem_info {
42+
flex: 1 1 0;
43+
display: flex;
44+
flex-direction: column;
45+
align-items: stretch;
46+
}
47+
48+
.mx_BeaconListItem_status {
49+
// override beacon status padding
50+
padding: 0 !important;
51+
margin-bottom: $spacing-8;
52+
53+
.mx_BeaconStatus_label {
54+
font-weight: $font-semi-bold;
55+
}
56+
}
57+
58+
.mx_BeaconListItem_lastUpdated {
59+
color: $tertiary-content;
60+
font-size: $font-10px;
61+
}

res/css/components/views/beacon/_BeaconStatus.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,7 @@ limitations under the License.
5959
.mx_BeaconStatus_expiryTime {
6060
color: $secondary-content;
6161
}
62+
63+
.mx_BeaconStatus_label {
64+
margin-bottom: 2px;
65+
}

res/css/components/views/beacon/_BeaconViewDialog.scss

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ limitations under the License.
2929
height: calc(80vh - 0.5px);
3030
overflow: hidden;
3131

32+
// sidebar is absolutely positioned inside
33+
position: relative;
34+
3235
.mx_Dialog_header {
3336
margin: 0px;
3437
padding: 0px;
@@ -40,7 +43,7 @@ limitations under the License.
4043

4144
.mx_Dialog_cancelButton {
4245
z-index: 4010;
43-
position: absolute;
46+
position: fixed;
4447
right: 5vw;
4548
top: 5vh;
4649
width: 20px;
@@ -77,3 +80,9 @@ limitations under the License.
7780
color: $secondary-content;
7881
margin-bottom: $spacing-16;
7982
}
83+
84+
.mx_BeaconViewDialog_viewListButton {
85+
position: absolute;
86+
top: $spacing-24;
87+
left: $spacing-24;
88+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
Copyright 2022 The Matrix.org Foundation C.I.C.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
.mx_DialogSidebar {
18+
position: absolute;
19+
top: 0;
20+
left: 0;
21+
height: 100%;
22+
width: 265px;
23+
24+
display: flex;
25+
flex-direction: column;
26+
27+
box-sizing: border-box;
28+
padding: $spacing-16;
29+
30+
background-color: $background;
31+
box-shadow: 0px 4px 4px $menu-box-shadow-color;
32+
}
33+
34+
.mx_DialogSidebar_header {
35+
display: flex;
36+
flex-direction: row;
37+
align-items: center;
38+
justify-content: space-between;
39+
40+
flex: 0 0;
41+
margin-bottom: $spacing-16;
42+
43+
color: $primary-content;
44+
}
45+
46+
.mx_DialogSidebar_closeButton {
47+
@mixin ButtonResetDefault;
48+
}
49+
50+
.mx_DialogSidebar_closeButtonIcon {
51+
color: $tertiary-content;
52+
height: 12px;
53+
}
54+
55+
.mx_DialogSidebar_list {
56+
@mixin ListResetDefault;
57+
flex: 1 1 0;
58+
width: 100%;
59+
overflow: auto;
60+
}

res/css/views/rooms/_RoomHeader.scss

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -141,17 +141,24 @@ limitations under the License.
141141
}
142142

143143
.mx_RoomHeader_topic {
144+
$lineHeight: $font-16px;
145+
$lines: 2;
146+
144147
flex: 1;
145148
color: $roomtopic-color;
146149
font-weight: 400;
147150
font-size: $font-13px;
151+
line-height: $lineHeight;
152+
max-height: calc($lineHeight * $lines);
153+
border-bottom: 1px solid transparent;
154+
148155
// to align baseline of topic with room name
149156
margin: 4px 7px 0;
157+
150158
overflow: hidden;
151-
text-overflow: ellipsis;
152-
border-bottom: 1px solid transparent;
153-
line-height: 1.2em;
154-
max-height: 2.4em;
159+
-webkit-line-clamp: $lines; // See: https://drafts.csswg.org/css-overflow-3/#webkit-line-clamp
160+
-webkit-box-orient: vertical;
161+
display: -webkit-box;
155162
}
156163

157164
.mx_RoomHeader_avatar {

res/css/views/typography/_Heading.scss

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,11 @@ limitations under the License.
3737
margin-inline: unset;
3838
margin-block: unset;
3939
}
40+
41+
.mx_Heading_h4 {
42+
font-size: $font-15px;
43+
font-weight: $font-semi-bold;
44+
line-height: $font-20px;
45+
margin-inline: unset;
46+
margin-block: unset;
47+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/*
2+
Copyright 2022 The Matrix.org Foundation C.I.C.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
import React, { useContext } from 'react';
18+
import { Beacon, BeaconEvent } from 'matrix-js-sdk/src/matrix';
19+
import { LocationAssetType } from 'matrix-js-sdk/src/@types/location';
20+
21+
import MatrixClientContext from '../../../contexts/MatrixClientContext';
22+
import { useEventEmitterState } from '../../../hooks/useEventEmitter';
23+
import { humanizeTime } from '../../../utils/humanize';
24+
import { _t } from '../../../languageHandler';
25+
import MemberAvatar from '../avatars/MemberAvatar';
26+
import CopyableText from '../elements/CopyableText';
27+
import BeaconStatus from './BeaconStatus';
28+
import { BeaconDisplayStatus } from './displayStatus';
29+
import StyledLiveBeaconIcon from './StyledLiveBeaconIcon';
30+
31+
interface Props {
32+
beacon: Beacon;
33+
}
34+
35+
const BeaconListItem: React.FC<Props> = ({ beacon }) => {
36+
const latestLocationState = useEventEmitterState(
37+
beacon,
38+
BeaconEvent.LocationUpdate,
39+
() => beacon.latestLocationState,
40+
);
41+
const matrixClient = useContext(MatrixClientContext);
42+
const room = matrixClient.getRoom(beacon.roomId);
43+
44+
if (!latestLocationState || !beacon.isLive) {
45+
return null;
46+
}
47+
48+
const isSelfLocation = beacon.beaconInfo.assetType === LocationAssetType.Self;
49+
const beaconMember = isSelfLocation ?
50+
room.getMember(beacon.beaconInfoOwner) :
51+
undefined;
52+
53+
const humanizedUpdateTime = humanizeTime(latestLocationState.timestamp);
54+
55+
return <li className='mx_BeaconListItem'>
56+
{ isSelfLocation ?
57+
<MemberAvatar
58+
className='mx_BeaconListItem_avatar'
59+
member={beaconMember}
60+
height={32}
61+
width={32}
62+
/> :
63+
<StyledLiveBeaconIcon className='mx_BeaconListItem_avatarIcon' />
64+
}
65+
<div className='mx_BeaconListItem_info'>
66+
<BeaconStatus
67+
className='mx_BeaconListItem_status'
68+
beacon={beacon}
69+
label={beaconMember?.name || beacon.beaconInfo.description || beacon.beaconInfoOwner}
70+
displayStatus={BeaconDisplayStatus.Active}
71+
>
72+
<CopyableText
73+
border={false}
74+
getTextToCopy={() => latestLocationState?.uri}
75+
/>
76+
</BeaconStatus>
77+
<span className='mx_BeaconListItem_lastUpdated'>{ _t("Updated %(humanizedUpdateTime)s", { humanizedUpdateTime }) }</span>
78+
</div>
79+
</li>;
80+
};
81+
82+
export default BeaconListItem;

src/components/views/beacon/BeaconStatus.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import { formatTime } from '../../../DateUtils';
2828
interface Props {
2929
displayStatus: BeaconDisplayStatus;
3030
displayLiveTimeRemaining?: boolean;
31+
withIcon?: boolean;
3132
beacon?: Beacon;
3233
label?: string;
3334
}
@@ -45,6 +46,7 @@ const BeaconStatus: React.FC<Props & HTMLProps<HTMLDivElement>> =
4546
label,
4647
className,
4748
children,
49+
withIcon,
4850
...rest
4951
}) => {
5052
const isIdle = displayStatus === BeaconDisplayStatus.Loading ||
@@ -54,11 +56,11 @@ const BeaconStatus: React.FC<Props & HTMLProps<HTMLDivElement>> =
5456
{...rest}
5557
className={classNames('mx_BeaconStatus', `mx_BeaconStatus_${displayStatus}`, className)}
5658
>
57-
<StyledLiveBeaconIcon
59+
{ withIcon && <StyledLiveBeaconIcon
5860
className='mx_BeaconStatus_icon'
5961
withError={displayStatus === BeaconDisplayStatus.Error}
6062
isIdle={isIdle}
61-
/>
63+
/> }
6264
<div className='mx_BeaconStatus_description'>
6365

6466
{ displayStatus === BeaconDisplayStatus.Loading && <span>{ _t('Loading live location...') }</span> }
@@ -68,7 +70,7 @@ const BeaconStatus: React.FC<Props & HTMLProps<HTMLDivElement>> =
6870

6971
{ displayStatus === BeaconDisplayStatus.Active && beacon && <>
7072
<>
71-
{ label }
73+
<span className='mx_BeaconStatus_label'>{ label }</span>
7274
{ displayLiveTimeRemaining ?
7375
<LiveTimeRemaining beacon={beacon} /> :
7476
<BeaconExpiryTime beacon={beacon} />

src/components/views/beacon/BeaconViewDialog.tsx

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

17-
import React from 'react';
17+
import React, { useState } from 'react';
1818
import { MatrixClient } from 'matrix-js-sdk/src/client';
1919
import {
2020
Beacon,
2121
Room,
2222
} from 'matrix-js-sdk/src/matrix';
2323
import maplibregl from 'maplibre-gl';
2424

25+
import { Icon as LiveLocationIcon } from '../../../../res/img/location/live-location.svg';
2526
import { useLiveBeacons } from '../../../utils/beacon/useLiveBeacons';
2627
import MatrixClientContext from '../../../contexts/MatrixClientContext';
2728
import BaseDialog from "../dialogs/BaseDialog";
@@ -34,6 +35,7 @@ import { getGeoUri } from '../../../utils/beacon';
3435
import { Icon as LocationIcon } from '../../../../res/img/element-icons/location.svg';
3536
import { _t } from '../../../languageHandler';
3637
import AccessibleButton from '../elements/AccessibleButton';
38+
import DialogSidebar from './DialogSidebar';
3739

3840
interface IProps extends IDialogProps {
3941
roomId: Room['roomId'];
@@ -64,6 +66,8 @@ const BeaconViewDialog: React.FC<IProps> = ({
6466
}) => {
6567
const liveBeacons = useLiveBeacons(roomId, matrixClient);
6668

69+
const [isSidebarOpen, setSidebarOpen] = useState(false);
70+
6771
const bounds = getBeaconBounds(liveBeacons);
6872
const centerGeoUri = focusBeacon?.latestLocationState?.uri || getBoundsCenter(bounds);
6973

@@ -108,6 +112,18 @@ const BeaconViewDialog: React.FC<IProps> = ({
108112
</AccessibleButton>
109113
</div>
110114
}
115+
{ isSidebarOpen ?
116+
<DialogSidebar beacons={liveBeacons} requestClose={() => setSidebarOpen(false)} /> :
117+
<AccessibleButton
118+
kind='primary'
119+
onClick={() => setSidebarOpen(true)}
120+
data-test-id='beacon-view-dialog-open-sidebar'
121+
className='mx_BeaconViewDialog_viewListButton'
122+
>
123+
<LiveLocationIcon height={12} />&nbsp;
124+
{ _t('View list') }
125+
</AccessibleButton>
126+
}
111127
</MatrixClientContext.Provider>
112128
</BaseDialog>
113129
);

0 commit comments

Comments
 (0)