@@ -41,7 +41,7 @@ const LocationShareTypeDropdown = ({
41
41
onChange,
42
42
} : IDropdownProps ) => {
43
43
const options = [
44
- // <div key={LocationShareType.Custom}>{ _t("Share custom location") }</div>,
44
+ < div key = { LocationShareType . Custom } > { _t ( "Share custom location" ) } </ div > ,
45
45
< div key = { LocationShareType . OnceOff } > { _t ( "Share my current location as a once off" ) } </ div > ,
46
46
// <div key={LocationShareType.OneMin}>{ _t("Share my current location for one minute") }</div>,
47
47
// <div key={LocationShareType.FiveMins}>{ _t("Share my current location for five minutes") }</div>,
@@ -56,7 +56,9 @@ const LocationShareTypeDropdown = ({
56
56
return < Dropdown
57
57
id = "mx_LocationShareTypeDropdown"
58
58
className = "mx_LocationShareTypeDropdown"
59
- onOptionChange = { ( key : string ) => { onChange ( LocationShareType [ LocationShareType [ parseInt ( key ) ] ] ) ; } }
59
+ onOptionChange = { ( key : string ) => {
60
+ onChange ( LocationShareType [ LocationShareType [ parseInt ( key ) ] ] ) ;
61
+ } }
60
62
menuWidth = { width }
61
63
label = { label }
62
64
value = { value . toString ( ) }
@@ -74,13 +76,14 @@ interface IState {
74
76
description : string ;
75
77
type : LocationShareType ;
76
78
position ?: GeolocationPosition ;
77
- manual : boolean ;
79
+ manualPosition ?: GeolocationPosition ;
78
80
error : Error ;
79
81
}
80
82
81
83
@replaceableComponent ( "views.location.LocationPicker" )
82
84
class LocationPicker extends React . Component < IProps , IState > {
83
85
private map : maplibregl . Map ;
86
+ private marker : maplibregl . Marker ;
84
87
private geolocate : maplibregl . GeolocateControl ;
85
88
86
89
constructor ( props ) {
@@ -90,7 +93,7 @@ class LocationPicker extends React.Component<IProps, IState> {
90
93
description : _t ( "My location" ) ,
91
94
type : LocationShareType . OnceOff ,
92
95
position : undefined ,
93
- manual : false ,
96
+ manualPosition : undefined ,
94
97
error : undefined ,
95
98
} ;
96
99
}
@@ -113,23 +116,63 @@ class LocationPicker extends React.Component<IProps, IState> {
113
116
} ) ;
114
117
this . map . addControl ( this . geolocate ) ;
115
118
116
- this . map . on ( 'error' , ( e ) => {
119
+ this . map . on ( 'error' , ( e ) => {
117
120
logger . error ( "Failed to load map: check map_style_url in config.json has a valid URL and API key" , e . error ) ;
118
121
this . setState ( { error : e . error } ) ;
119
122
} ) ;
120
123
121
- this . map . on ( 'load' , ( ) => {
124
+ this . map . on ( 'load' , ( ) => {
122
125
this . geolocate . trigger ( ) ;
123
126
} ) ;
124
127
128
+ this . map . on ( 'click' , ( e ) => {
129
+ this . addMarker ( e . lngLat ) ;
130
+ this . storeManualPosition ( e . lngLat ) ;
131
+ this . setState ( { type : LocationShareType . Custom } ) ;
132
+ } ) ;
133
+
125
134
this . geolocate . on ( 'geolocate' , this . onGeolocate ) ;
126
135
}
127
136
137
+ private addMarker ( lngLat : maplibregl . LngLat ) : void {
138
+ if ( this . marker ) return ;
139
+ this . marker = new maplibregl . Marker ( {
140
+ draggable : true ,
141
+ } )
142
+ . setLngLat ( lngLat )
143
+ . addTo ( this . map )
144
+ . on ( 'dragend' , ( ) => {
145
+ this . storeManualPosition ( this . marker . getLngLat ( ) ) ;
146
+ } ) ;
147
+ }
148
+
149
+ private removeMarker ( ) : void {
150
+ if ( ! this . marker ) return ;
151
+ this . marker . remove ( ) ;
152
+ this . marker = undefined ;
153
+ }
154
+
155
+ private storeManualPosition ( lngLat : maplibregl . LngLat ) : void {
156
+ const manualPosition : GeolocationPosition = {
157
+ coords : {
158
+ longitude : lngLat . lng ,
159
+ latitude : lngLat . lat ,
160
+ altitude : undefined ,
161
+ accuracy : undefined ,
162
+ altitudeAccuracy : undefined ,
163
+ heading : undefined ,
164
+ speed : undefined ,
165
+ } ,
166
+ timestamp : Date . now ( ) ,
167
+ } ;
168
+ this . setState ( { manualPosition } ) ;
169
+ }
170
+
128
171
componentWillUnmount ( ) {
129
172
this . geolocate . off ( 'geolocate' , this . onGeolocate ) ;
130
173
}
131
174
132
- private onGeolocate = ( position ) => {
175
+ private onGeolocate = ( position : GeolocationPosition ) => {
133
176
this . setState ( { position } ) ;
134
177
} ;
135
178
@@ -146,16 +189,33 @@ class LocationPicker extends React.Component<IProps, IState> {
146
189
} ;
147
190
148
191
private onOk = ( ) => {
192
+ const position = ( this . state . type == LocationShareType . Custom ) ?
193
+ this . state . manualPosition : this . state . position ;
194
+
149
195
this . props . onChoose (
150
- this . state . position ? this . getGeoUri ( this . state . position ) : undefined ,
151
- this . state . position ? this . state . position . timestamp : undefined ,
196
+ position ? this . getGeoUri ( position ) : undefined ,
197
+ position ? position . timestamp : undefined ,
152
198
this . state . type ,
153
199
this . state . description ,
154
200
) ;
155
201
this . props . onFinished ( ) ;
156
202
} ;
157
203
158
204
private onTypeChange = ( type : LocationShareType ) => {
205
+ if ( type == LocationShareType . Custom ) {
206
+ if ( ! this . state . manualPosition ) {
207
+ this . setState ( { manualPosition : this . state . position } ) ;
208
+ }
209
+ if ( this . state . manualPosition ) {
210
+ this . addMarker ( new maplibregl . LngLat (
211
+ this . state . manualPosition ?. coords . longitude ,
212
+ this . state . manualPosition ?. coords . latitude ,
213
+ ) ) ;
214
+ }
215
+ } else {
216
+ this . removeMarker ( ) ;
217
+ }
218
+
159
219
this . setState ( { type } ) ;
160
220
} ;
161
221
@@ -189,7 +249,7 @@ class LocationPicker extends React.Component<IProps, IState> {
189
249
< DialogButtons primaryButton = { _t ( 'Share' ) }
190
250
onPrimaryButtonClick = { this . onOk }
191
251
onCancel = { this . props . onFinished }
192
- disabled = { ! this . state . position } />
252
+ primaryDisabled = { ! this . state . position } />
193
253
</ form >
194
254
</ div >
195
255
</ div >
0 commit comments