Tidy location code (#7402)
							parent
							
								
									fb494a5098
								
							
						
					
					
						commit
						670d7824ec
					
				| 
						 | 
				
			
			@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
 | 
			
		|||
limitations under the License.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import React, { SyntheticEvent } from 'react';
 | 
			
		||||
import maplibregl from 'maplibre-gl';
 | 
			
		||||
import { logger } from "matrix-js-sdk/src/logger";
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -40,16 +40,36 @@ const LocationShareTypeDropdown = ({
 | 
			
		|||
    onChange,
 | 
			
		||||
}: IDropdownProps) => {
 | 
			
		||||
    const options = [
 | 
			
		||||
        <div key={LocationShareType.Custom}>{ _t("Share custom location") }</div>,
 | 
			
		||||
        <div key={LocationShareType.OnceOff}>{ _t("Share my current location as a once off") }</div>,
 | 
			
		||||
        // <div key={LocationShareType.OneMin}>{ _t("Share my current location for one minute") }</div>,
 | 
			
		||||
        // <div key={LocationShareType.FiveMins}>{ _t("Share my current location for five minutes") }</div>,
 | 
			
		||||
        // <div key={LocationShareType.ThirtyMins}>{ _t("Share my current location for thirty minutes") }</div>,
 | 
			
		||||
        // <div key={LocationShareType.OneHour}>{ _t("Share my current location for one hour") }</div>,
 | 
			
		||||
        // <div key={LocationShareType.ThreeHours}>{ _t("Share my current location for three hours") }</div>,
 | 
			
		||||
        // <div key={LocationShareType.SixHours}>{ _t("Share my current location for six hours") }</div>,
 | 
			
		||||
        // <div key={LocationShareType.OneDay}>{ _t("Share my current location for one day") }</div>,
 | 
			
		||||
        // <div key={LocationShareType.Forever}>{ _t("Share my current location until I disable it") }</div>,
 | 
			
		||||
        <div key={LocationShareType.Custom}>{
 | 
			
		||||
            _t("Share custom location")
 | 
			
		||||
        }</div>,
 | 
			
		||||
        <div key={LocationShareType.OnceOff}>{
 | 
			
		||||
            _t("Share my current location as a once off")
 | 
			
		||||
        }</div>,
 | 
			
		||||
        // <div key={LocationShareType.OneMin}>{
 | 
			
		||||
        //     _t("Share my current location for one minute")
 | 
			
		||||
        // }</div>,
 | 
			
		||||
        // <div key={LocationShareType.FiveMins}>{
 | 
			
		||||
        //     _t("Share my current location for five minutes")
 | 
			
		||||
        // }</div>,
 | 
			
		||||
        // <div key={LocationShareType.ThirtyMins}>{
 | 
			
		||||
        //     _t("Share my current location for thirty minutes")
 | 
			
		||||
        // }</div>,
 | 
			
		||||
        // <div key={LocationShareType.OneHour}>{
 | 
			
		||||
        //     _t("Share my current location for one hour")
 | 
			
		||||
        // }</div>,
 | 
			
		||||
        // <div key={LocationShareType.ThreeHours}>{
 | 
			
		||||
        //     _t("Share my current location for three hours")
 | 
			
		||||
        // }</div>,
 | 
			
		||||
        // <div key={LocationShareType.SixHours}>{
 | 
			
		||||
        //     _t("Share my current location for six hours")
 | 
			
		||||
        // }</div>,
 | 
			
		||||
        // <div key={LocationShareType.OneDay}>{
 | 
			
		||||
        //     _t("Share my current location for one day")
 | 
			
		||||
        // }</div>,
 | 
			
		||||
        // <div key={LocationShareType.Forever}>{
 | 
			
		||||
        //     _t("Share my current location until I disable it")
 | 
			
		||||
        // }</div>,
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    return <Dropdown
 | 
			
		||||
| 
						 | 
				
			
			@ -67,8 +87,13 @@ const LocationShareTypeDropdown = ({
 | 
			
		|||
};
 | 
			
		||||
 | 
			
		||||
interface IProps {
 | 
			
		||||
    onChoose(uri: string, ts: number, type: LocationShareType, description: string): boolean;
 | 
			
		||||
    onFinished();
 | 
			
		||||
    onChoose(
 | 
			
		||||
        uri: string,
 | 
			
		||||
        ts: number,
 | 
			
		||||
        type: LocationShareType,
 | 
			
		||||
        description: string,
 | 
			
		||||
    ): boolean;
 | 
			
		||||
    onFinished(ev?: SyntheticEvent): void;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface IState {
 | 
			
		||||
| 
						 | 
				
			
			@ -85,7 +110,7 @@ class LocationPicker extends React.Component<IProps, IState> {
 | 
			
		|||
    private marker: maplibregl.Marker;
 | 
			
		||||
    private geolocate: maplibregl.GeolocateControl;
 | 
			
		||||
 | 
			
		||||
    constructor(props) {
 | 
			
		||||
    constructor(props: IProps) {
 | 
			
		||||
        super(props);
 | 
			
		||||
 | 
			
		||||
        this.state = {
 | 
			
		||||
| 
						 | 
				
			
			@ -117,8 +142,11 @@ class LocationPicker extends React.Component<IProps, IState> {
 | 
			
		|||
            this.map.addControl(this.geolocate);
 | 
			
		||||
 | 
			
		||||
            this.map.on('error', (e) => {
 | 
			
		||||
                logger.error("Failed to load map: check map_style_url in config.json has a valid URL and API key",
 | 
			
		||||
                    e.error);
 | 
			
		||||
                logger.error(
 | 
			
		||||
                    "Failed to load map: check map_style_url in config.json "
 | 
			
		||||
                        + "has a valid URL and API key",
 | 
			
		||||
                    e.error,
 | 
			
		||||
                );
 | 
			
		||||
                this.setState({ error: e.error });
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -246,7 +274,10 @@ class LocationPicker extends React.Component<IProps, IState> {
 | 
			
		|||
                        <DialogButtons primaryButton={_t('Share')}
 | 
			
		||||
                            onPrimaryButtonClick={this.onOk}
 | 
			
		||||
                            onCancel={this.props.onFinished}
 | 
			
		||||
                            primaryDisabled={!this.state.position && !this.state.manualPosition} />
 | 
			
		||||
                            primaryDisabled={
 | 
			
		||||
                                !this.state.position &&
 | 
			
		||||
                                !this.state.manualPosition
 | 
			
		||||
                            } />
 | 
			
		||||
                    </form>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
| 
						 | 
				
			
			@ -255,12 +286,19 @@ class LocationPicker extends React.Component<IProps, IState> {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
export function getGeoUri(position: GeolocationPosition): string {
 | 
			
		||||
    return (`geo:${ position.coords.latitude },` +
 | 
			
		||||
            position.coords.longitude +
 | 
			
		||||
            ( position.coords.altitude !== undefined ?
 | 
			
		||||
                `,${ position.coords.altitude }` : '' ) +
 | 
			
		||||
            ( position.coords.accuracy !== undefined ?
 | 
			
		||||
                `;u=${ position.coords.accuracy }` : '' ));
 | 
			
		||||
    const lat = position.coords.latitude;
 | 
			
		||||
    const lon = position.coords.longitude;
 | 
			
		||||
    const alt = (
 | 
			
		||||
        position.coords.altitude !== undefined
 | 
			
		||||
            ? `,${position.coords.altitude}`
 | 
			
		||||
            : ""
 | 
			
		||||
    );
 | 
			
		||||
    const acc = (
 | 
			
		||||
        position.coords.accuracy !== undefined
 | 
			
		||||
            ? `;u=${ position.coords.accuracy }`
 | 
			
		||||
            : ""
 | 
			
		||||
    );
 | 
			
		||||
    return `geo:${lat},${lon}${alt}${acc}`;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default LocationPicker;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -55,7 +55,8 @@ export default class MLocationBody extends React.Component<IBodyProps, IState> {
 | 
			
		|||
 | 
			
		||||
    componentDidMount() {
 | 
			
		||||
        const config = SdkConfig.get();
 | 
			
		||||
        const coordinates = new maplibregl.LngLat(this.coords.longitude, this.coords.latitude);
 | 
			
		||||
        const coordinates = new maplibregl.LngLat(
 | 
			
		||||
            this.coords.longitude, this.coords.latitude);
 | 
			
		||||
 | 
			
		||||
        this.map = new maplibregl.Map({
 | 
			
		||||
            container: this.getBodyId(),
 | 
			
		||||
| 
						 | 
				
			
			@ -74,7 +75,11 @@ export default class MLocationBody extends React.Component<IBodyProps, IState> {
 | 
			
		|||
            .addTo(this.map);
 | 
			
		||||
 | 
			
		||||
        this.map.on('error', (e)=>{
 | 
			
		||||
            logger.error("Failed to load map: check map_style_url in config.json has a valid URL and API key", e.error);
 | 
			
		||||
            logger.error(
 | 
			
		||||
                "Failed to load map: check map_style_url in config.json has a "
 | 
			
		||||
                + "valid URL and API key",
 | 
			
		||||
                e.error,
 | 
			
		||||
            );
 | 
			
		||||
            this.setState({ error: e.error });
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,7 +13,7 @@ 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, { ComponentProps, createRef } from 'react';
 | 
			
		||||
import React, { ComponentProps, createRef, ReactElement } from 'react';
 | 
			
		||||
import classNames from 'classnames';
 | 
			
		||||
import { MatrixEvent, IEventRelation } from "matrix-js-sdk/src/models/event";
 | 
			
		||||
import { Room } from "matrix-js-sdk/src/models/room";
 | 
			
		||||
| 
						 | 
				
			
			@ -138,13 +138,21 @@ interface ILocationButtonProps extends Pick<ICollapsibleButtonProps, "narrowMode
 | 
			
		|||
    narrowMode: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const LocationButton: React.FC<ILocationButtonProps> = ({ shareLocation, menuPosition, narrowMode }) => {
 | 
			
		||||
const LocationButton: React.FC<ILocationButtonProps> = (
 | 
			
		||||
    { shareLocation, menuPosition, narrowMode },
 | 
			
		||||
) => {
 | 
			
		||||
    const [menuDisplayed, button, openMenu, closeMenu] = useContextMenu();
 | 
			
		||||
 | 
			
		||||
    let contextMenu;
 | 
			
		||||
    let contextMenu: ReactElement;
 | 
			
		||||
    if (menuDisplayed) {
 | 
			
		||||
        const position = menuPosition ?? aboveLeftOf(button.current.getBoundingClientRect());
 | 
			
		||||
        contextMenu = <ContextMenu {...position} onFinished={closeMenu} managed={false}>
 | 
			
		||||
        const position = menuPosition ?? aboveLeftOf(
 | 
			
		||||
            button.current.getBoundingClientRect());
 | 
			
		||||
 | 
			
		||||
        contextMenu = <ContextMenu
 | 
			
		||||
            {...position}
 | 
			
		||||
            onFinished={closeMenu}
 | 
			
		||||
            managed={false}
 | 
			
		||||
        >
 | 
			
		||||
            <LocationPicker onChoose={shareLocation} onFinished={closeMenu} />
 | 
			
		||||
        </ContextMenu>;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
 | 
			
		|||
limitations under the License.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
import "../../../skinned-sdk";
 | 
			
		||||
import "../../../skinned-sdk"; // Must be first for skinning to work
 | 
			
		||||
import { getGeoUri } from "../../../../src/components/views/location/LocationPicker";
 | 
			
		||||
 | 
			
		||||
describe("LocationPicker", () => {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue