Live location sharing - update live location tiles (PSF-1027) (#8649)
* update map svg Signed-off-by: Kerry Archibald <kerrya@element.io> * add map fallback component, update styls Signed-off-by: Kerry Archibald <kerrya@element.io> * update purple location icon style Signed-off-by: Kerry Archibald <kerrya@element.io> * fussy import ordering Signed-off-by: Kerry Archibald <kerrya@element.io> * tidy Signed-off-by: Kerry Archibald <kerrya@element.io>
This commit is contained in:
parent
30b03776b8
commit
804ddbb332
11 changed files with 182 additions and 85 deletions
|
@ -19,6 +19,7 @@
|
||||||
@import "./components/views/location/_LiveDurationDropdown.scss";
|
@import "./components/views/location/_LiveDurationDropdown.scss";
|
||||||
@import "./components/views/location/_LocationShareMenu.scss";
|
@import "./components/views/location/_LocationShareMenu.scss";
|
||||||
@import "./components/views/location/_MapError.scss";
|
@import "./components/views/location/_MapError.scss";
|
||||||
|
@import "./components/views/location/_MapFallback.scss";
|
||||||
@import "./components/views/location/_Marker.scss";
|
@import "./components/views/location/_Marker.scss";
|
||||||
@import "./components/views/location/_ShareDialogButtons.scss";
|
@import "./components/views/location/_ShareDialogButtons.scss";
|
||||||
@import "./components/views/location/_ShareType.scss";
|
@import "./components/views/location/_ShareType.scss";
|
||||||
|
|
|
@ -59,23 +59,6 @@ limitations under the License.
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_BeaconViewDialog_mapFallback {
|
|
||||||
box-sizing: border-box;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
background: url('$(res)/img/location/map.svg');
|
|
||||||
background-size: cover;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_BeaconViewDialog_mapFallbackIcon {
|
|
||||||
width: 65px;
|
|
||||||
margin-bottom: $spacing-16;
|
|
||||||
color: $quaternary-content;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_BeaconViewDialog_mapFallbackMessage {
|
.mx_BeaconViewDialog_mapFallbackMessage {
|
||||||
color: $secondary-content;
|
color: $secondary-content;
|
||||||
margin-bottom: $spacing-16;
|
margin-bottom: $spacing-16;
|
||||||
|
|
|
@ -23,7 +23,7 @@ limitations under the License.
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
|
|
||||||
background-color: $location-live-color;
|
background-color: $location-live-color;
|
||||||
border-color: $location-live-secondary-color;
|
border-color: $location-live-color;
|
||||||
padding: 2px;
|
padding: 2px;
|
||||||
// colors icon
|
// colors icon
|
||||||
color: white;
|
color: white;
|
||||||
|
|
45
res/css/components/views/location/_MapFallback.scss
Normal file
45
res/css/components/views/location/_MapFallback.scss
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
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_MapFallback {
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
position: relative;
|
||||||
|
z-index: 0;
|
||||||
|
|
||||||
|
background-color: $system;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_MapFallback_bg {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
min-height: 100%;
|
||||||
|
min-width: 100%;
|
||||||
|
color: $quinary-content;
|
||||||
|
z-index: -1;
|
||||||
|
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_MapFallback_icon {
|
||||||
|
width: 65px;
|
||||||
|
margin-bottom: $spacing-16;
|
||||||
|
color: $quaternary-content;
|
||||||
|
}
|
|
@ -26,30 +26,17 @@ limitations under the License.
|
||||||
.mx_MBeaconBody_map {
|
.mx_MBeaconBody_map {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
z-index: 0; // keeps the entire map under the message action bar
|
z-index: 0; // keeps the entire map under the message action bars
|
||||||
|
|
||||||
&:not(.mx_MBeaconBody_mapFallback) {
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_MBeaconBody_mapFallback {
|
.mx_MBeaconBody_mapFallback {
|
||||||
box-sizing: border-box;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
// pushes spinner/icon up
|
// pushes spinner/icon up
|
||||||
// to appear more centered with the footer
|
// to appear more centered with the footer
|
||||||
padding-bottom: 50px;
|
padding-bottom: 50px;
|
||||||
|
|
||||||
background: url('$(res)/img/location/map.svg');
|
cursor: default;
|
||||||
background-size: cover;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_MBeaconBody_mapFallbackIcon {
|
|
||||||
width: 65px;
|
|
||||||
color: $quaternary-content;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_MBeaconBody_chin {
|
.mx_MBeaconBody_chin {
|
||||||
|
|
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 828 B |
|
@ -32,12 +32,12 @@ import ZoomButtons from '../location/ZoomButtons';
|
||||||
import BeaconMarker from './BeaconMarker';
|
import BeaconMarker from './BeaconMarker';
|
||||||
import { Bounds, getBeaconBounds } from '../../../utils/beacon/bounds';
|
import { Bounds, getBeaconBounds } from '../../../utils/beacon/bounds';
|
||||||
import { getGeoUri } from '../../../utils/beacon';
|
import { getGeoUri } from '../../../utils/beacon';
|
||||||
import { Icon as LocationIcon } from '../../../../res/img/element-icons/location.svg';
|
|
||||||
import { _t } from '../../../languageHandler';
|
import { _t } from '../../../languageHandler';
|
||||||
import AccessibleButton from '../elements/AccessibleButton';
|
import AccessibleButton from '../elements/AccessibleButton';
|
||||||
import DialogSidebar from './DialogSidebar';
|
import DialogSidebar from './DialogSidebar';
|
||||||
import DialogOwnBeaconStatus from './DialogOwnBeaconStatus';
|
import DialogOwnBeaconStatus from './DialogOwnBeaconStatus';
|
||||||
import BeaconStatusTooltip from './BeaconStatusTooltip';
|
import BeaconStatusTooltip from './BeaconStatusTooltip';
|
||||||
|
import MapFallback from '../location/MapFallback';
|
||||||
|
|
||||||
interface IProps extends IDialogProps {
|
interface IProps extends IDialogProps {
|
||||||
roomId: Room['roomId'];
|
roomId: Room['roomId'];
|
||||||
|
@ -110,11 +110,10 @@ const BeaconViewDialog: React.FC<IProps> = ({
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
</Map> :
|
</Map> :
|
||||||
<div
|
<MapFallback
|
||||||
data-test-id='beacon-view-dialog-map-fallback'
|
data-test-id='beacon-view-dialog-map-fallback'
|
||||||
className='mx_BeaconViewDialog_map mx_BeaconViewDialog_mapFallback'
|
className='mx_BeaconViewDialog_map'
|
||||||
>
|
>
|
||||||
<LocationIcon className='mx_BeaconViewDialog_mapFallbackIcon' />
|
|
||||||
<span className='mx_BeaconViewDialog_mapFallbackMessage'>{ _t('No live locations') }</span>
|
<span className='mx_BeaconViewDialog_mapFallbackMessage'>{ _t('No live locations') }</span>
|
||||||
<AccessibleButton
|
<AccessibleButton
|
||||||
kind='primary'
|
kind='primary'
|
||||||
|
@ -123,7 +122,7 @@ const BeaconViewDialog: React.FC<IProps> = ({
|
||||||
>
|
>
|
||||||
{ _t('Close') }
|
{ _t('Close') }
|
||||||
</AccessibleButton>
|
</AccessibleButton>
|
||||||
</div>
|
</MapFallback>
|
||||||
}
|
}
|
||||||
{ isSidebarOpen ?
|
{ isSidebarOpen ?
|
||||||
<DialogSidebar beacons={liveBeacons} requestClose={() => setSidebarOpen(false)} /> :
|
<DialogSidebar beacons={liveBeacons} requestClose={() => setSidebarOpen(false)} /> :
|
||||||
|
|
39
src/components/views/location/MapFallback.tsx
Normal file
39
src/components/views/location/MapFallback.tsx
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
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 from 'react';
|
||||||
|
import classNames from 'classnames';
|
||||||
|
|
||||||
|
import { Icon as LocationMarkerIcon } from '../../../../res/img/element-icons/location.svg';
|
||||||
|
import { Icon as MapFallbackImage } from '../../../../res/img/location/map.svg';
|
||||||
|
import Spinner from '../elements/Spinner';
|
||||||
|
|
||||||
|
interface Props extends React.HTMLAttributes<HTMLDivElement> {
|
||||||
|
className?: string;
|
||||||
|
isLoading?: boolean;
|
||||||
|
children?: React.ReactNode | React.ReactNodeArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
const MapFallback: React.FC<Props> = ({ className, isLoading, children, ...rest }) => {
|
||||||
|
return <div className={classNames('mx_MapFallback', className)} {...rest}>
|
||||||
|
<MapFallbackImage className='mx_MapFallback_bg' />
|
||||||
|
{ /* <div className='mx_MapFallback_bg'/> */ }
|
||||||
|
{ isLoading ? <Spinner h={32} w={32} /> : <LocationMarkerIcon className='mx_MapFallback_icon' /> }
|
||||||
|
{ children }
|
||||||
|
</div>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default MapFallback;
|
|
@ -19,7 +19,6 @@ import { Beacon, BeaconEvent, MatrixEvent } from 'matrix-js-sdk/src/matrix';
|
||||||
import { BeaconLocationState } from 'matrix-js-sdk/src/content-helpers';
|
import { BeaconLocationState } from 'matrix-js-sdk/src/content-helpers';
|
||||||
import { randomString } from 'matrix-js-sdk/src/randomstring';
|
import { randomString } from 'matrix-js-sdk/src/randomstring';
|
||||||
|
|
||||||
import { Icon as LocationMarkerIcon } from '../../../../res/img/element-icons/location.svg';
|
|
||||||
import MatrixClientContext from '../../../contexts/MatrixClientContext';
|
import MatrixClientContext from '../../../contexts/MatrixClientContext';
|
||||||
import { useEventEmitterState } from '../../../hooks/useEventEmitter';
|
import { useEventEmitterState } from '../../../hooks/useEventEmitter';
|
||||||
import { _t } from '../../../languageHandler';
|
import { _t } from '../../../languageHandler';
|
||||||
|
@ -28,8 +27,8 @@ import { useBeacon } from '../../../utils/beacon';
|
||||||
import { isSelfLocation } from '../../../utils/location';
|
import { isSelfLocation } from '../../../utils/location';
|
||||||
import { BeaconDisplayStatus, getBeaconDisplayStatus } from '../beacon/displayStatus';
|
import { BeaconDisplayStatus, getBeaconDisplayStatus } from '../beacon/displayStatus';
|
||||||
import BeaconStatus from '../beacon/BeaconStatus';
|
import BeaconStatus from '../beacon/BeaconStatus';
|
||||||
import Spinner from '../elements/Spinner';
|
|
||||||
import Map from '../location/Map';
|
import Map from '../location/Map';
|
||||||
|
import MapFallback from '../location/MapFallback';
|
||||||
import SmartMarker from '../location/SmartMarker';
|
import SmartMarker from '../location/SmartMarker';
|
||||||
import OwnBeaconStatus from '../beacon/OwnBeaconStatus';
|
import OwnBeaconStatus from '../beacon/OwnBeaconStatus';
|
||||||
import BeaconViewDialog from '../beacon/BeaconViewDialog';
|
import BeaconViewDialog from '../beacon/BeaconViewDialog';
|
||||||
|
@ -134,12 +133,10 @@ const MBeaconBody: React.FC<IBodyProps> = React.forwardRef(({ mxEvent }, ref) =>
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
</Map>
|
</Map>
|
||||||
: <div className='mx_MBeaconBody_map mx_MBeaconBody_mapFallback'>
|
: <MapFallback
|
||||||
{ displayStatus === BeaconDisplayStatus.Loading ?
|
isLoading={displayStatus === BeaconDisplayStatus.Loading}
|
||||||
<Spinner h={32} w={32} /> :
|
className='mx_MBeaconBody_map mx_MBeaconBody_mapFallback'
|
||||||
<LocationMarkerIcon className='mx_MBeaconBody_mapFallbackIcon' />
|
/>
|
||||||
}
|
|
||||||
</div>
|
|
||||||
}
|
}
|
||||||
{ isOwnBeacon ?
|
{ isOwnBeacon ?
|
||||||
<OwnBeaconStatus
|
<OwnBeaconStatus
|
||||||
|
|
|
@ -1,12 +1,20 @@
|
||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
exports[`<BeaconViewDialog /> renders a fallback when no live beacons remain 1`] = `
|
exports[`<BeaconViewDialog /> renders a fallback when no live beacons remain 1`] = `
|
||||||
<div
|
Array [
|
||||||
className="mx_BeaconViewDialog_map mx_BeaconViewDialog_mapFallback"
|
<MapFallback
|
||||||
|
className="mx_BeaconViewDialog_map"
|
||||||
data-test-id="beacon-view-dialog-map-fallback"
|
data-test-id="beacon-view-dialog-map-fallback"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="mx_BeaconViewDialog_mapFallbackIcon"
|
className="mx_MapFallback mx_BeaconViewDialog_map"
|
||||||
|
data-test-id="beacon-view-dialog-map-fallback"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="mx_MapFallback_bg"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
className="mx_MapFallback_icon"
|
||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
className="mx_BeaconViewDialog_mapFallbackMessage"
|
className="mx_BeaconViewDialog_mapFallbackMessage"
|
||||||
|
@ -33,5 +41,43 @@ exports[`<BeaconViewDialog /> renders a fallback when no live beacons remain 1`]
|
||||||
Close
|
Close
|
||||||
</div>
|
</div>
|
||||||
</AccessibleButton>
|
</AccessibleButton>
|
||||||
</div>
|
</div>
|
||||||
|
</MapFallback>,
|
||||||
|
<div
|
||||||
|
className="mx_MapFallback mx_BeaconViewDialog_map"
|
||||||
|
data-test-id="beacon-view-dialog-map-fallback"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="mx_MapFallback_bg"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
className="mx_MapFallback_icon"
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
className="mx_BeaconViewDialog_mapFallbackMessage"
|
||||||
|
>
|
||||||
|
No live locations
|
||||||
|
</span>
|
||||||
|
<AccessibleButton
|
||||||
|
data-test-id="beacon-view-dialog-fallback-close"
|
||||||
|
element="div"
|
||||||
|
kind="primary"
|
||||||
|
onClick={[MockFunction]}
|
||||||
|
role="button"
|
||||||
|
tabIndex={0}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="mx_AccessibleButton mx_AccessibleButton_hasKind mx_AccessibleButton_kind_primary"
|
||||||
|
data-test-id="beacon-view-dialog-fallback-close"
|
||||||
|
onClick={[MockFunction]}
|
||||||
|
onKeyDown={[Function]}
|
||||||
|
onKeyUp={[Function]}
|
||||||
|
role="button"
|
||||||
|
tabIndex={0}
|
||||||
|
>
|
||||||
|
Close
|
||||||
|
</div>
|
||||||
|
</AccessibleButton>
|
||||||
|
</div>,
|
||||||
|
]
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -116,7 +116,7 @@ describe('<MBeaconBody />', () => {
|
||||||
makeRoomWithStateEvents([beaconInfoEvent], { roomId, mockClient });
|
makeRoomWithStateEvents([beaconInfoEvent], { roomId, mockClient });
|
||||||
const component = getComponent({ mxEvent: beaconInfoEvent });
|
const component = getComponent({ mxEvent: beaconInfoEvent });
|
||||||
act(() => {
|
act(() => {
|
||||||
component.find('.mx_MBeaconBody_map').simulate('click');
|
component.find('.mx_MBeaconBody_map').at(0).simulate('click');
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(modalSpy).not.toHaveBeenCalled();
|
expect(modalSpy).not.toHaveBeenCalled();
|
||||||
|
@ -230,7 +230,7 @@ describe('<MBeaconBody />', () => {
|
||||||
const component = getComponent({ mxEvent: aliceBeaconInfo });
|
const component = getComponent({ mxEvent: aliceBeaconInfo });
|
||||||
|
|
||||||
act(() => {
|
act(() => {
|
||||||
component.find('.mx_MBeaconBody_map').simulate('click');
|
component.find('.mx_MBeaconBody_map').at(0).simulate('click');
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(modalSpy).not.toHaveBeenCalled();
|
expect(modalSpy).not.toHaveBeenCalled();
|
||||||
|
@ -264,7 +264,7 @@ describe('<MBeaconBody />', () => {
|
||||||
const component = getComponent({ mxEvent: aliceBeaconInfo });
|
const component = getComponent({ mxEvent: aliceBeaconInfo });
|
||||||
|
|
||||||
act(() => {
|
act(() => {
|
||||||
component.find('.mx_MBeaconBody_map').simulate('click');
|
component.find('.mx_MBeaconBody_map').at(0).simulate('click');
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(modalSpy).not.toHaveBeenCalled();
|
expect(modalSpy).not.toHaveBeenCalled();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue