You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			135 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Dart
		
	
			
		
		
	
	
			135 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Dart
		
	
import 'dart:async';
 | 
						|
 | 
						|
import 'package:flutter/cupertino.dart';
 | 
						|
import 'package:flutter/material.dart';
 | 
						|
 | 
						|
import 'package:geolocator/geolocator.dart';
 | 
						|
import 'package:matrix/matrix.dart';
 | 
						|
 | 
						|
import 'package:fluffychat/l10n/l10n.dart';
 | 
						|
import 'package:fluffychat/pages/chat/events/map_bubble.dart';
 | 
						|
import 'package:fluffychat/widgets/adaptive_dialogs/adaptive_dialog_action.dart';
 | 
						|
import 'package:fluffychat/widgets/future_loading_dialog.dart';
 | 
						|
 | 
						|
class SendLocationDialog extends StatefulWidget {
 | 
						|
  final Room room;
 | 
						|
 | 
						|
  const SendLocationDialog({
 | 
						|
    required this.room,
 | 
						|
    super.key,
 | 
						|
  });
 | 
						|
 | 
						|
  @override
 | 
						|
  SendLocationDialogState createState() => SendLocationDialogState();
 | 
						|
}
 | 
						|
 | 
						|
class SendLocationDialogState extends State<SendLocationDialog> {
 | 
						|
  bool disabled = false;
 | 
						|
  bool denied = false;
 | 
						|
  bool isSending = false;
 | 
						|
  Position? position;
 | 
						|
  Object? error;
 | 
						|
 | 
						|
  @override
 | 
						|
  void initState() {
 | 
						|
    super.initState();
 | 
						|
    requestLocation();
 | 
						|
  }
 | 
						|
 | 
						|
  Future<void> requestLocation() async {
 | 
						|
    if (!(await Geolocator.isLocationServiceEnabled())) {
 | 
						|
      setState(() => disabled = true);
 | 
						|
      return;
 | 
						|
    }
 | 
						|
    var permission = await Geolocator.checkPermission();
 | 
						|
    if (permission == LocationPermission.denied) {
 | 
						|
      permission = await Geolocator.requestPermission();
 | 
						|
      if (permission == LocationPermission.denied) {
 | 
						|
        setState(() => denied = true);
 | 
						|
        return;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    if (permission == LocationPermission.deniedForever) {
 | 
						|
      setState(() => denied = true);
 | 
						|
      return;
 | 
						|
    }
 | 
						|
    try {
 | 
						|
      Position position;
 | 
						|
      try {
 | 
						|
        position = await Geolocator.getCurrentPosition(
 | 
						|
          locationSettings: const LocationSettings(
 | 
						|
            accuracy: LocationAccuracy.best,
 | 
						|
            timeLimit: Duration(seconds: 30),
 | 
						|
          ),
 | 
						|
        );
 | 
						|
      } on TimeoutException {
 | 
						|
        position = await Geolocator.getCurrentPosition(
 | 
						|
          locationSettings: const LocationSettings(
 | 
						|
            accuracy: LocationAccuracy.medium,
 | 
						|
            timeLimit: Duration(seconds: 30),
 | 
						|
          ),
 | 
						|
        );
 | 
						|
      }
 | 
						|
      setState(() => this.position = position);
 | 
						|
    } catch (e) {
 | 
						|
      setState(() => error = e);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  void sendAction() async {
 | 
						|
    setState(() => isSending = true);
 | 
						|
    final body =
 | 
						|
        'https://www.openstreetmap.org/?mlat=${position!.latitude}&mlon=${position!.longitude}#map=16/${position!.latitude}/${position!.longitude}';
 | 
						|
    final uri =
 | 
						|
        'geo:${position!.latitude},${position!.longitude};u=${position!.accuracy}';
 | 
						|
    await showFutureLoadingDialog(
 | 
						|
      context: context,
 | 
						|
      future: () => widget.room.sendLocation(body, uri),
 | 
						|
    );
 | 
						|
    Navigator.of(context, rootNavigator: false).pop();
 | 
						|
  }
 | 
						|
 | 
						|
  @override
 | 
						|
  Widget build(BuildContext context) {
 | 
						|
    Widget contentWidget;
 | 
						|
    if (position != null) {
 | 
						|
      contentWidget = MapBubble(
 | 
						|
        latitude: position!.latitude,
 | 
						|
        longitude: position!.longitude,
 | 
						|
      );
 | 
						|
    } else if (disabled) {
 | 
						|
      contentWidget = Text(L10n.of(context).locationDisabledNotice);
 | 
						|
    } else if (denied) {
 | 
						|
      contentWidget = Text(L10n.of(context).locationPermissionDeniedNotice);
 | 
						|
    } else if (error != null) {
 | 
						|
      contentWidget =
 | 
						|
          Text(L10n.of(context).errorObtainingLocation(error.toString()));
 | 
						|
    } else {
 | 
						|
      contentWidget = Row(
 | 
						|
        mainAxisSize: MainAxisSize.min,
 | 
						|
        mainAxisAlignment: MainAxisAlignment.center,
 | 
						|
        children: [
 | 
						|
          const CupertinoActivityIndicator(),
 | 
						|
          const SizedBox(width: 12),
 | 
						|
          Text(L10n.of(context).obtainingLocation),
 | 
						|
        ],
 | 
						|
      );
 | 
						|
    }
 | 
						|
    return AlertDialog.adaptive(
 | 
						|
      title: Text(L10n.of(context).shareLocation),
 | 
						|
      content: contentWidget,
 | 
						|
      actions: [
 | 
						|
        AdaptiveDialogAction(
 | 
						|
          onPressed: Navigator.of(context, rootNavigator: false).pop,
 | 
						|
          child: Text(L10n.of(context).cancel),
 | 
						|
        ),
 | 
						|
        if (position != null)
 | 
						|
          AdaptiveDialogAction(
 | 
						|
            onPressed: isSending ? null : sendAction,
 | 
						|
            child: Text(L10n.of(context).send),
 | 
						|
          ),
 | 
						|
      ],
 | 
						|
    );
 | 
						|
  }
 | 
						|
}
 |