Untitled

 avatar
unknown
plain_text
5 months ago
8.0 kB
3
Indexable
import 'dart:async';

import 'package:courier/features/map/bloc/map_order_state.dart';
import 'package:courier/widgets/base_appbar.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:geolocator/geolocator.dart';
import 'package:get_it/get_it.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:yandex_mapkit_lite/yandex_mapkit_lite.dart';

import '../../data/models/orders/on_map/order_map_list.dart';
import '../../data/repositories/orders/abstract_orders_repository.dart';
import 'bloc/map_order_bloc.dart';
import 'bloc/map_order_event.dart';

class MapScreen extends StatefulWidget {
  const MapScreen({super.key});

  @override
  _MapScreenState createState() => _MapScreenState();
}

class _MapScreenState extends State<MapScreen> {
  late YandexMapController _controller;
  List<MapObject> mapObjects = [];
  final double _zoomLevel = 13.0;
  BitmapDescriptor? flipPointIcon;
  BitmapDescriptor? personIcon;
  final _mapOrderListBloc = MapOrderBloc(
    GetIt.I<AbstractOrdersRepository>(),
  );

  @override
  void initState() {
    super.initState();
    _mapOrderListBloc.add(LoadMapOrderList(null));
    requestLocationPermission();
  }

  Future<void> requestLocationPermission() async {
    var status = await Permission.location.request();
    if (status.isGranted) {
      // showUserLocation();
    } else {
      print('Location permission denied');
    }
  }

  Future<void> showUserLocation() async {
    Position position = await Geolocator.getCurrentPosition(
      desiredAccuracy: LocationAccuracy.high,
    );

    await Future.delayed(const Duration(seconds: 1));
    _controller.moveCamera(
      CameraUpdate.newCameraPosition(
        CameraPosition(
          target:
              Point(latitude: position.latitude, longitude: position.longitude),
          zoom: _zoomLevel,
        ),
      ),
    );

    final userLocationPlacemark = PlacemarkMapObject(
      mapId: const MapObjectId('user_location'),
      point: Point(latitude: position.latitude, longitude: position.longitude),
      icon: PlacemarkIcon.single(
        PlacemarkIconStyle(
          image: BitmapDescriptor.fromAssetImage(
              'assets/images/ic_yandex_navigator.png'),
          scale: 1.0,
        ),
      ),
    );

    setState(() {
      mapObjects.add(userLocationPlacemark);
    });
  }

  _zoomIn() async {
    final currentPosition = await _controller.getCameraPosition();
    await _controller.moveCamera(
      CameraUpdate.newCameraPosition(
        CameraPosition(
          target: currentPosition.target,
          zoom: currentPosition.zoom + 1,
        ),
      ),
      animation: const MapAnimation(
        type: MapAnimationType.linear,
        duration: 0.5,
      ),
    );
  }

  _zoomOut() async {
    final currentPosition = await _controller.getCameraPosition();
    await _controller.moveCamera(
      CameraUpdate.newCameraPosition(
        CameraPosition(
          target: currentPosition.target,
          zoom: currentPosition.zoom - 1,
        ),
      ),
      animation: const MapAnimation(
        type: MapAnimationType.linear,
        duration: 0.5,
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: const BaseAppBar(title: 'Заказы на карте'),
      body: RefreshIndicator(
        onRefresh: () async {
          final completer = Completer();
          _mapOrderListBloc.add(LoadMapOrderList(completer));
          return completer.future;
        },
        child: BlocBuilder<MapOrderBloc, MapOrderState>(
          bloc: _mapOrderListBloc,
          builder: (context, state) {
            if (state is MapOrderListLoaded) {
              mapObjects = _createMarkers(state.list);
              return Stack(
                children: [
                  YandexMap(
                    mapObjects: mapObjects,
                    onMapCreated: (YandexMapController controller) {
                      _controller = controller;
                      showUserLocation();
                    },
                  ),
                  Align(
                    alignment: Alignment.centerLeft,
                    child: Padding(
                      padding: const EdgeInsets.all(16.0),
                      child: Column(
                        mainAxisSize: MainAxisSize.min,
                        children: [
                          FloatingActionButton(
                            onPressed: _zoomIn,
                            backgroundColor: Colors.white,
                            child: Image.asset("assets/images/ic_zoom_in.png",
                                height: 24),
                          ),
                          const SizedBox(height: 8),
                          FloatingActionButton(
                            onPressed: _zoomOut,
                            backgroundColor: Colors.white,
                            child: Image.asset("assets/images/ic_zoom_out.png",
                                height: 24),
                          ),
                          const SizedBox(height: 8),
                          FloatingActionButton(
                            onPressed: showUserLocation,
                            backgroundColor: Colors.white,
                            child: Image.asset(
                                "assets/images/ic_get_current_geo.png",
                                height: 24),
                          ),
                        ],
                      ),
                    ),
                  ),
                ],
              );
            }
            if (state is MapOrderListLoadingFailure) {
              return Center(
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: [
                    const Text(
                      'Что-то пошло не так',
                      style: TextStyle(fontSize: 24),
                    ),
                    const Text(
                      'Пожалуйста, попробуйте позже',
                      style: TextStyle(fontSize: 16),
                    ),
                    const SizedBox(height: 30),
                    TextButton(
                      onPressed: () {
                        _mapOrderListBloc.add(LoadMapOrderList(null));
                      },
                      child: const Text("Обновить"),
                    ),
                  ],
                ),
              );
            }
            return const Center(child: CircularProgressIndicator());
          },
        ),
      ),
    );
  }

  List<MapObject> _createMarkers(OrderMapList list) {
    final markers = list.rows.map((order) {
      return PlacemarkMapObject(
        mapId: MapObjectId(order.orderGroup.toString()),
        opacity: 1,
        point: Point(
          longitude: double.parse(order.longitude!),
          latitude: double.parse(order.latitude!),
        ),
        icon: PlacemarkIcon.single(
          PlacemarkIconStyle(
            image: order.deliveryMethodBaseName == "Point"
                ? BitmapDescriptor.fromAssetImage(
                    'assets/images/ic_flip_point_marker.png')
                : order.deliveryMethodBaseName == "Tastamat"
                    ? BitmapDescriptor.fromAssetImage(
                        'assets/images/ic_tastamat_marker.png')
                    : BitmapDescriptor.fromAssetImage(
                        'assets/images/ic_person_marker.png'),
            scale: 1.0,
          ),
        ),
        onTap: (PlacemarkMapObject self, Point point) {
          Navigator.of(context).pushNamed('/order_detail', arguments: {
            'orderGroupId': order.orderGroup,
            'orderNum': order.orderGroup
          });
        },
      );
    }).toList();
    return markers;
  }
}
Editor is loading...
Leave a Comment