@@ -29,29 +29,43 @@ import { IDialogProps } from "../dialogs/IDialogProps";
29
29
import Map from '../location/Map' ;
30
30
import ZoomButtons from '../location/ZoomButtons' ;
31
31
import BeaconMarker from './BeaconMarker' ;
32
+ import { Bounds , getBeaconBounds } from '../../../utils/beacon/bounds' ;
33
+ import { getGeoUri } from '../../../utils/beacon' ;
34
+ import { Icon as LocationIcon } from '../../../../res/img/element-icons/location.svg' ;
35
+ import { _t } from '../../../languageHandler' ;
36
+ import AccessibleButton from '../elements/AccessibleButton' ;
32
37
33
38
interface IProps extends IDialogProps {
34
39
roomId : Room [ 'roomId' ] ;
35
40
matrixClient : MatrixClient ;
41
+ // open the map centered on this beacon's location
42
+ focusBeacon ?: Beacon ;
36
43
}
37
44
38
- // TODO actual center is coming soon
39
- // for now just center around first beacon in list
40
- const getMapCenterUri = ( beacons : Beacon [ ] ) : string => {
41
- const firstBeaconWithLocation = beacons . find ( beacon => beacon . latestLocationState ) ;
42
-
43
- return firstBeaconWithLocation ?. latestLocationState ?. uri ;
45
+ const getBoundsCenter = ( bounds : Bounds ) : string | undefined => {
46
+ if ( ! bounds ) {
47
+ return ;
48
+ }
49
+ return getGeoUri ( {
50
+ latitude : ( bounds . north + bounds . south ) / 2 ,
51
+ longitude : ( bounds . east + bounds . west ) / 2 ,
52
+ timestamp : Date . now ( ) ,
53
+ } ) ;
44
54
} ;
45
55
46
56
/**
47
57
* Dialog to view live beacons maximised
48
58
*/
49
- const BeaconViewDialog : React . FC < IProps > = ( { roomId, matrixClient, onFinished } ) => {
59
+ const BeaconViewDialog : React . FC < IProps > = ( {
60
+ focusBeacon,
61
+ roomId,
62
+ matrixClient,
63
+ onFinished,
64
+ } ) => {
50
65
const liveBeacons = useLiveBeacons ( roomId , matrixClient ) ;
51
66
52
- const mapCenterUri = getMapCenterUri ( liveBeacons ) ;
53
- // TODO probably show loader or placeholder when there is no location
54
- // to center the map on
67
+ const bounds = getBeaconBounds ( liveBeacons ) ;
68
+ const centerGeoUri = focusBeacon ?. latestLocationState ?. uri || getBoundsCenter ( bounds ) ;
55
69
56
70
return (
57
71
< BaseDialog
@@ -60,9 +74,10 @@ const BeaconViewDialog: React.FC<IProps> = ({ roomId, matrixClient, onFinished }
60
74
fixedWidth = { false }
61
75
>
62
76
< MatrixClientContext . Provider value = { matrixClient } >
63
- < Map
77
+ { ! ! bounds ? < Map
64
78
id = 'mx_BeaconViewDialog'
65
- centerGeoUri = { mapCenterUri }
79
+ bounds = { bounds }
80
+ centerGeoUri = { centerGeoUri }
66
81
interactive
67
82
className = "mx_BeaconViewDialog_map"
68
83
>
@@ -77,7 +92,22 @@ const BeaconViewDialog: React.FC<IProps> = ({ roomId, matrixClient, onFinished }
77
92
< ZoomButtons map = { map } />
78
93
</ >
79
94
}
80
- </ Map >
95
+ </ Map > :
96
+ < div
97
+ data-test-id = 'beacon-view-dialog-map-fallback'
98
+ className = 'mx_BeaconViewDialog_map mx_BeaconViewDialog_mapFallback'
99
+ >
100
+ < LocationIcon className = 'mx_BeaconViewDialog_mapFallbackIcon' />
101
+ < span className = 'mx_BeaconViewDialog_mapFallbackMessage' > { _t ( 'No live locations' ) } </ span >
102
+ < AccessibleButton
103
+ kind = 'primary'
104
+ onClick = { onFinished }
105
+ data-test-id = 'beacon-view-dialog-fallback-close'
106
+ >
107
+ { _t ( 'Close' ) }
108
+ </ AccessibleButton >
109
+ </ div >
110
+ }
81
111
</ MatrixClientContext . Provider >
82
112
</ BaseDialog >
83
113
) ;
0 commit comments