diff --git a/assets/images/map-pin.png b/assets/images/map-pin.png new file mode 100644 index 0000000..2414e34 Binary files /dev/null and b/assets/images/map-pin.png differ diff --git a/assets/images/map-pin.svg b/assets/images/map-pin.svg new file mode 100644 index 0000000..bc93c65 --- /dev/null +++ b/assets/images/map-pin.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/devtools_options.yaml b/devtools_options.yaml new file mode 100644 index 0000000..7e7e7f6 --- /dev/null +++ b/devtools_options.yaml @@ -0,0 +1 @@ +extensions: diff --git a/ios/Podfile b/ios/Podfile index 279576f..cf37528 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -38,4 +38,7 @@ post_install do |installer| installer.pods_project.targets.each do |target| flutter_additional_ios_build_settings(target) end + installer.pods_project.build_configurations.each do |config| + config.build_settings["EXCLUDED_ARCHS[sdk=iphonesimulator*]"] = "arm64" + end end diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 90bd32b..6ca0c09 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -10,6 +10,15 @@ PODS: - GoogleMaps/Base (6.2.1) - GoogleMaps/Maps (6.2.1): - GoogleMaps/Base + - Mapbox-iOS-SDK (6.4.1): + - MapboxMobileEvents (~> 0.10.12) + - mapbox_gl (0.0.1): + - Flutter + - Mapbox-iOS-SDK (~> 6.4.0) + - MapboxAnnotationExtension (~> 0.0.1-beta.1) + - MapboxAnnotationExtension (0.0.1-beta.2): + - Mapbox-iOS-SDK (~> 6.0) + - MapboxMobileEvents (0.10.14) - path_provider_foundation (0.0.1): - Flutter - FlutterMacOS @@ -22,6 +31,7 @@ DEPENDENCIES: - audioplayers_darwin (from `.symlinks/plugins/audioplayers_darwin/ios`) - Flutter (from `Flutter`) - google_maps_flutter_ios (from `.symlinks/plugins/google_maps_flutter_ios/ios`) + - mapbox_gl (from `.symlinks/plugins/mapbox_gl/ios`) - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`) - video_player_avfoundation (from `.symlinks/plugins/video_player_avfoundation/ios`) - wakelock (from `.symlinks/plugins/wakelock/ios`) @@ -29,6 +39,9 @@ DEPENDENCIES: SPEC REPOS: trunk: - GoogleMaps + - Mapbox-iOS-SDK + - MapboxAnnotationExtension + - MapboxMobileEvents EXTERNAL SOURCES: audioplayers_darwin: @@ -37,6 +50,8 @@ EXTERNAL SOURCES: :path: Flutter google_maps_flutter_ios: :path: ".symlinks/plugins/google_maps_flutter_ios/ios" + mapbox_gl: + :path: ".symlinks/plugins/mapbox_gl/ios" path_provider_foundation: :path: ".symlinks/plugins/path_provider_foundation/darwin" video_player_avfoundation: @@ -49,10 +64,14 @@ SPEC CHECKSUMS: Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 google_maps_flutter_ios: 3e0b99383a8003b8169d06e7e324170bd0424105 GoogleMaps: 20d7b12be49a14287f797e88e0e31bc4156aaeb4 + Mapbox-iOS-SDK: f870f83cbdc7aa4a74afcee143aafb0dae390c82 + mapbox_gl: 33c5ab6306cbfa72289bb3606d2cd2e8baee9ff0 + MapboxAnnotationExtension: 4eee6c26349ef6d909f1a23a7eae2d0f7ca5fa7d + MapboxMobileEvents: 5a172cc9bbf8ac0e45ba86095cbee685ede248cc path_provider_foundation: eaf5b3e458fc0e5fbb9940fb09980e853fe058b8 video_player_avfoundation: 81e49bb3d9fb63dccf9fa0f6d877dc3ddbeac126 wakelock: d0fc7c864128eac40eba1617cb5264d9c940b46f -PODFILE CHECKSUM: c4c93c5f6502fe2754f48404d3594bf779584011 +PODFILE CHECKSUM: 3ea40ac0978505df4275c2e24526ea6055c94efa COCOAPODS: 1.15.2 diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index 3c940b6..15c7836 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -2,6 +2,14 @@ + io.flutter.embedded_views_preview + + MGLMapboxMetricsEnabledSettingShownInApp + + NSLocationWhenInUseUsageDescription + Shows your location on the map and helps improve the map + NSLocationAlwaysUsageDescription + Shows your location on the map and helps improve the map CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleDisplayName diff --git a/lib/additionals/location.dart b/lib/additionals/location.dart index e81802c..86e0dde 100644 --- a/lib/additionals/location.dart +++ b/lib/additionals/location.dart @@ -1,6 +1,6 @@ import 'package:audioplayers/audioplayers.dart'; import 'package:flutter/material.dart'; -import 'package:google_maps_flutter/google_maps_flutter.dart'; +import 'package:mapbox_gl/mapbox_gl.dart'; class Location { int id; diff --git a/lib/additionals/locations_list.dart b/lib/additionals/locations_list.dart index ce5d160..8772b4f 100644 --- a/lib/additionals/locations_list.dart +++ b/lib/additionals/locations_list.dart @@ -1,6 +1,6 @@ import 'package:audioplayers/audioplayers.dart'; import 'package:flutter/material.dart'; -import 'package:google_maps_flutter/google_maps_flutter.dart'; +import 'package:mapbox_gl/mapbox_gl.dart'; import 'location.dart'; @@ -18,7 +18,7 @@ class LocationList { 'assets/images/burning_man/burning_man_2.jpg', ], audio: AssetSource('audio/Burning_Man.mp3'), - coords: const LatLng(32.9172973, -96.7637959), + coords: const LatLng(40.7829, -119.2006), interviewers: ["Unknown"], interviewees: ["Brad Pitt"], video: 'assets/video/Burning_Man.mp4'), @@ -34,7 +34,7 @@ class LocationList { 'assets/images/brazil_carnaval/brazil_carnaval_2.jpg', ], audio: AssetSource('audio/Brazil_Carnaval.mp3'), - coords: const LatLng(32.8437457, -96.8326761), + coords: const LatLng(-22.9068, -43.1729), interviewers: ["Unknown", "Angelina Jolie"], interviewees: ["Leonardo DiCaprio", "Jennifer Aniston"], video: 'assets/video/Brazil_Carnaval.mp4'), @@ -50,7 +50,7 @@ class LocationList { 'assets/images/oktoberfest/oktoberfest_2.jpg', ], audio: AssetSource('audio/Oktoberfest.mp3'), - coords: const LatLng(32.8439148, -96.8299776), + coords: const LatLng(48.1351, 11.5820), interviewers: ["Tom Hanks", "Meryl Streep"], interviewees: ["George Clooney", "Julia Roberts"], video: 'assets/video/Oktoberfest.mp4', @@ -68,7 +68,7 @@ class LocationList { 'assets/images/day_of_dead/day_of_dead_2.jpg', ], audio: AssetSource('audio/DayOfDead.mp3'), - coords: const LatLng(32.7824583, -96.7949716), + coords: const LatLng(19.4326, -99.1332), interviewers: ["Denzel Washington", "Charlize Theron"], interviewees: ["Johnny Depp", "Sandra Bullock"], video: 'assets/video/DayOfDead.mp4', @@ -84,7 +84,7 @@ class LocationList { 'assets/images/rodeo/rodeo_2.jpg', ], audio: AssetSource('audio/Rodeo.mp3'), - coords: const LatLng(32.8334168, -96.8075467), + coords: const LatLng(29.7604, -95.3698), interviewers: ["Robert Downey Jr."], interviewees: ["Nicole Kidman"], video: 'assets/video/Rodeo.mp4', diff --git a/lib/screens/map_screen.dart b/lib/screens/map_screen.dart index 7794054..d12fcf0 100644 --- a/lib/screens/map_screen.dart +++ b/lib/screens/map_screen.dart @@ -2,10 +2,11 @@ import 'package:flutter/material.dart'; import 'package:my_app/additionals/locations_list.dart'; import 'package:my_app/main.dart'; import 'package:my_app/widgets/carousel.dart'; +import 'package:my_app/widgets/locations_carousel.dart'; +import 'package:my_app/widgets/map_box_gl.dart'; import 'package:my_app/widgets/panel_widget.dart'; import 'package:provider/provider.dart'; import 'package:sliding_up_panel/sliding_up_panel.dart'; -import 'package:my_app/widgets/map_google.dart'; import 'package:my_app/widgets/short_info_block.dart'; import 'package:my_app/widgets/full_info_block.dart'; import 'package:my_app/widgets/menu.dart'; @@ -49,9 +50,7 @@ class MapScreenState extends State { return Stack(children: [ Scaffold( - body: SafeArea( - top: true, - child: SlidingUpPanel( + body: SlidingUpPanel( minHeight: panelHeightClosed, maxHeight: panelHeightOpen, parallaxEnabled: false, @@ -59,10 +58,11 @@ class MapScreenState extends State { color: themeOverlayColor, borderRadius: const BorderRadius.vertical(top: Radius.circular(15)), onPanelSlide: _snapPointPanel, - panelSnapping: false, + panelSnapping: true, snapPoint: 0.5, backdropEnabled: true, backdropTapClosesPanel: true, + boxShadow: null, panelBuilder: (controller) => PanelWidget( controller: controller, panelController: panelController), panel: Container( @@ -71,27 +71,29 @@ class MapScreenState extends State { // Close Icons Row( children: [ - IconButton( - icon: const Icon(Icons.close), - iconSize: 30.0, - onPressed: () { - _closePanel(); - if (appState.currentLocation != null && - appState.experianceType == "Virtual") { - final currentIndex = - locations.indexOf(appState.currentLocation!); - if (currentIndex < locations.length - 1) { - appState.changeCurrentLocation( - locations[currentIndex + 1]); - } - } - }, - ), + Container( + padding: const EdgeInsets.only(left: 16.0, top: 16.0), + child: IconButton( + icon: const Icon(Icons.close), + iconSize: 30.0, + onPressed: () { + _closePanel(); + if (appState.currentLocation != null && + appState.experianceType == "Virtual") { + final currentIndex = + locations.indexOf(appState.currentLocation!); + if (currentIndex < locations.length - 1) { + appState.changeCurrentLocation( + locations[currentIndex + 1]); + } + } + }, + )), ], ), // Full height block Visibility( - visible: previousPosition > 0.5, + visible: previousPosition > 0.5 + 0.01, child: FullInfoBlock( closePanel: _closePanel, )), @@ -100,23 +102,27 @@ class MapScreenState extends State { visible: previousPosition <= 0.5, child: const ShortInfoBlock()), ])), - body: Center( - child: MapGoogle( - togglePanel: _togglePanel, - ), - ), + body: MapBoxGl( + togglePanel: _togglePanel, panelPosition: previousPosition), ), - )), + ), Positioned( left: 25.0, bottom: 80.0, child: FloatingActionButton( + backgroundColor: themeSecondaryColor, onPressed: () { _showMenuModal(context); }, child: const Icon(Icons.menu), ), ), + Positioned( + right: 25.0, + left: 100.0, + bottom: 50.0, + child: LocationsCarousel(togglePanel: _togglePanel), + ), ]); } diff --git a/lib/widgets/locations_carousel.dart b/lib/widgets/locations_carousel.dart new file mode 100644 index 0000000..c931075 --- /dev/null +++ b/lib/widgets/locations_carousel.dart @@ -0,0 +1,126 @@ +import 'package:flutter/material.dart'; +import 'package:my_app/additionals/location.dart'; +import 'package:my_app/additionals/locations_list.dart'; +import 'package:my_app/main.dart'; +import 'package:my_app/utils/constants.dart'; +import 'package:carousel_slider/carousel_slider.dart'; +import 'package:provider/provider.dart'; + +class LocationsCarousel extends StatefulWidget { + final void Function(double position) togglePanel; + + const LocationsCarousel({ + Key? key, + required this.togglePanel, + }) : super(key: key); + + @override + CarouselState createState() => CarouselState(); +} + +class CarouselState extends State { + final List locations = LocationList.locations; + late AppState appStateRead; + + @override + void initState() { + super.initState(); + appStateRead = Provider.of(context, listen: false); + } + + _handleSelectLocation(Location locatin) { + appStateRead.changeCurrentLocation(locatin); + } + + // _onPageChanged(int idx, CarouselPageChangedReason bbb) { + // appStateRead.changeCurrentLocation(locations[idx]); + // _showVideoModal(); + // } + + // void _showVideoModal() { + // showDialog( + // context: context, + // barrierColor: Colors.black.withOpacity(0.5), + // builder: (BuildContext context) { + // return VideoModalContent( + // togglePanel: widget.togglePanel, + // currentLocation: Provider.of(context).currentLocation); + // }, + // ); + // } + + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.all(8), + child: CarouselSlider( + options: CarouselOptions( + height: 100, + viewportFraction: 0.7, + initialPage: 0, + enableInfiniteScroll: true, + reverse: false, + autoPlay: false, + autoPlayInterval: const Duration(seconds: 3), + autoPlayAnimationDuration: const Duration(milliseconds: 800), + autoPlayCurve: Curves.fastOutSlowIn, + enlargeCenterPage: true, + // onPageChanged: _onPageChanged, + ), + items: locations.map((location) { + AppState appStateWatch = Provider.of(context); + bool isSelected = appStateWatch.currentLocation?.id == location.id; + + return Material( + color: isSelected ? Colors.red : themeSecondaryColor, + borderRadius: BorderRadius.circular(15), + child: InkWell( + onTap: () { + _handleSelectLocation(location); + }, + child: Container( + padding: const EdgeInsets.all(8), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + width: 70.0, + height: 70.0, + decoration: BoxDecoration( + border: Border.all( + color: Colors.white, + width: 1, + ), + borderRadius: BorderRadius.circular(15), + image: DecorationImage( + image: location.preview, + fit: BoxFit.cover, + ), + ), + ), + Expanded( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 8), + child: Center( + child: Text( + location.name, + style: const TextStyle( + color: Colors.white, + fontSize: 18, + fontWeight: FontWeight.w700, + decoration: TextDecoration.none), + textAlign: TextAlign.center, + ), + ), + ), + ), + ], + ), + ), + )); + }).toList(), + ), + ); + } +} diff --git a/lib/widgets/map_box_gl.dart b/lib/widgets/map_box_gl.dart new file mode 100644 index 0000000..fd77035 --- /dev/null +++ b/lib/widgets/map_box_gl.dart @@ -0,0 +1,161 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:mapbox_gl/mapbox_gl.dart' as mapbox; +import 'package:my_app/additionals/location.dart'; +import 'package:my_app/additionals/locations_list.dart'; +import 'package:my_app/main.dart'; +import 'package:my_app/widgets/video_modal.dart'; +import 'package:provider/provider.dart'; + +class MapBoxGl extends StatefulWidget { + final void Function(double position) togglePanel; + final double panelPosition; + + const MapBoxGl({ + Key? key, + required this.togglePanel, + required this.panelPosition, + }) : super(key: key); + + @override + State createState() => MapBoxGlState(); +} + +class MapBoxGlState extends State with TickerProviderStateMixin { + final List locations = LocationList.locations; + late mapbox.MapboxMapController mapController; + late AppState appState; + Location? _previousLocation; + + @override + void initState() { + super.initState(); + appState = Provider.of(context, listen: false); + appState.addListener(_onAppStateChange); + } + + @override + void dispose() { + mapController.dispose(); + super.dispose(); + } + + void _onAppStateChange() { + final currentLocation = appState.currentLocation; + if (_previousLocation != currentLocation && currentLocation != null) { + _previousLocation = currentLocation; + mapController.animateCamera( + mapbox.CameraUpdate.newCameraPosition( + mapbox.CameraPosition( + target: currentLocation.coords, + zoom: 15.0, + ), + ), + ); + } + if (appState.experianceType == "Explore" && appState.isUserAcceptInfo) { + widget.togglePanel(0.5); + } + + if (appState.experianceType == "Virtual" && appState.isUserAcceptInfo) { + _showVideoModal(); + } + } + + void _showVideoModal() { + showDialog( + context: context, + barrierColor: Colors.black.withOpacity(0.5), + builder: (BuildContext context) { + return VideoModalContent( + togglePanel: widget.togglePanel, + currentLocation: Provider.of(context).currentLocation); + }, + ); + } + + void _onMapCreated(mapbox.MapboxMapController mapboxMapController) { + mapController = mapboxMapController; + + WidgetsBinding.instance.addPostFrameCallback((_) { + appState.changeCurrentLocation(locations.first); + mapboxMapController.animateCamera( + mapbox.CameraUpdate.newCameraPosition( + mapbox.CameraPosition( + target: locations.first.coords, + zoom: 15.0, + ), + ), + ); + }); + } + + void _onStyleLoadedCallback() async { + var byteData = await rootBundle.load("assets/images/map-pin.png"); + var markerImage = byteData.buffer.asUint8List(); + + mapController.addImage("marker", markerImage); + + for (var location in locations) { + mapController.addSymbol( + mapbox.SymbolOptions( + geometry: location.coords, + textField: location.name, // Имя места в качестве текста маркера + iconImage: "marker", + iconSize: 3, + iconAnchor: "center", + textOffset: const Offset(0, -3), + ), + ); + mapController.onSymbolTapped.add((symbol) { + for (var location in locations) { + if (symbol.options.geometry == location.coords) { + if (appState.experianceType == "Explore") { + appState.changeCurrentLocation(location); + widget.togglePanel(0.5); + mapController.animateCamera( + mapbox.CameraUpdate.newCameraPosition(mapbox.CameraPosition( + target: location.coords, + zoom: 10.0, + )), + ); + } + break; + } + } + }); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: SizedBox( + width: double.infinity, + height: double.infinity, + child: Container( + width: 200, + height: 200, + padding: const EdgeInsets.all(8), + decoration: BoxDecoration( + color: Colors.red, + border: Border.all( + color: Colors.green, + width: 1, + ), + ), + child: mapbox.MapboxMap( + onMapCreated: _onMapCreated, + onStyleLoadedCallback: _onStyleLoadedCallback, + accessToken: + "sk.eyJ1IjoibmF6aXRvIiwiYSI6ImNsdG9tZjU5MDBpcXkya3JxMG1zNGhsY2UifQ.vXfTkSYvSq8xv5m6W2hYlQ", + initialCameraPosition: const mapbox.CameraPosition( + target: mapbox.LatLng(0.0, 0.0), + zoom: 12.0, + ), + styleString: 'mapbox://styles/mapbox/outdoors-v11', + )), + ), + ); + } +} diff --git a/lib/widgets/map_box_gl_flutter_map.dart b/lib/widgets/map_box_gl_flutter_map.dart new file mode 100644 index 0000000..9d64bcd --- /dev/null +++ b/lib/widgets/map_box_gl_flutter_map.dart @@ -0,0 +1,51 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_map/flutter_map.dart'; +import 'package:latlong2/latlong.dart'; + +class MapBoxGlFlutterMap extends StatefulWidget { + final void Function(double position) togglePanel; + + const MapBoxGlFlutterMap({ + Key? key, + required this.togglePanel, + }) : super(key: key); + + @override + State createState() => MapBoxGlFlutterMapState(); +} + +class MapBoxGlFlutterMapState extends State { + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: const Text('MapBox')), + body: FlutterMap( + options: MapOptions( + center: LatLng(27.175002, 78.0421170902921), + zoom: 5.0, + ), + children: [ + TileLayer( + urlTemplate: + "https://api.mapbox.com/styles/v1/nazito/cltsbz3mu013401nr2q1k38gt/tiles/256/{z}/{x}/{y}@2x?access_token=pk.eyJ1IjoibmF6aXRvIiwiYSI6ImNsdG9tODJhbTBqOGIycXJxcmNyODV1ZWgifQ.ymFrBXv0XLNCxrtsqqKA5w", + // "https://api.mapbox.com/styles/v1/nazito/cltri2f8200n101pce9gig0l7/tiles/256/{z}/{x}/{y}@2x?access_token=pk.eyJ1IjoibmF6aXRvIiwiYSI6ImNsdG9tODJhbTBqOGIycXJxcmNyODV1ZWgifQ.ymFrBXv0XLNCxrtsqqKA5w", + // "https://api.mapbox.com/styles/v1/acidhue/cjvb13pgd12t01flpd97ub8dx/tiles/256/{z}/{x}/{y}@2x?access_token=pk.eyJ1IjoibmF6aXRvIiwiYSI6ImNsdG9tODJhbTBqOGIycXJxcmNyODV1ZWgifQ.ymFrBXv0XLNCxrtsqqKA5w", + + additionalOptions: const { + 'accessToken': + 'pk.eyJ1IjoibmF6aXRvIiwiYSI6ImNsdG9tODJhbTBqOGIycXJxcmNyODV1ZWgifQ.ymFrBXv0XLNCxrtsqqKA5w', + 'id': 'mapbox://styles/nazito/cltrag3cw00di01pjf49wfi6m' + }, + // urlTemplate: + // "https://api.mapbox.com/styles/v1/{id}/tiles/512/{z}/{x}/{y}@2x?access_token=pk.eyJ1IjoibmF6aXRvIiwiYSI6ImNsdG9tODJhbTBqOGIycXJxcmNyODV1ZWgifQ.ymFrBXv0XLNCxrtsqqKA5w", + // additionalOptions: const { + // 'accessToken': + // 'pk.eyJ1IjoibmF6aXRvIiwiYSI6ImNsdG9tODJhbTBqOGIycXJxcmNyODV1ZWgifQ.ymFrBXv0XLNCxrtsqqKA5w', + // 'id': 'mapbox.mapbox-streets-v8', + // }, + ) + ], + ), + ); + } +} diff --git a/lib/widgets/map_google.dart b/lib/widgets/map_google.dart index c476d25..bbb2467 100644 --- a/lib/widgets/map_google.dart +++ b/lib/widgets/map_google.dart @@ -1,178 +1,178 @@ -import 'dart:async'; -import 'package:flick_video_player/flick_video_player.dart'; -import 'package:my_app/additionals/locations_list.dart'; -import 'package:my_app/main.dart'; -import 'package:my_app/widgets/video_modal.dart'; -import 'package:flutter/material.dart'; -import 'package:google_maps_flutter/google_maps_flutter.dart'; -import 'package:my_app/additionals/location.dart'; -import 'package:provider/provider.dart'; - -class MapGoogle extends StatefulWidget { - final void Function(double position) togglePanel; - - const MapGoogle({ - Key? key, - required this.togglePanel, - }) : super(key: key); - - @override - State createState() => MapGoogleState(); -} - -class MapGoogleState extends State with TickerProviderStateMixin { - late AppState appState; - String mapTheme = ''; - late FlickManager flickManager; - final Completer _controller = - Completer(); - final List locations = LocationList.locations; - Location? _previousLocation; - - @override - void initState() { - super.initState(); - - DefaultAssetBundle.of(context) - .loadString('assets/maptheme/dark_theme.json') - .then((value) => mapTheme = value); - appState = Provider.of(context, listen: false); - } - - @override - void didChangeDependencies() { - super.didChangeDependencies(); - final currentLocation = appState.currentLocation; - - if (_previousLocation != currentLocation && - currentLocation != null && - appState.experianceType == "Virtual") { - _previousLocation = currentLocation; - _moveToNextMarker(currentLocation); - } - } - - Future moveToMarker(Marker marker) async { - if (appState.experianceType == "Virtual") { - final GoogleMapController controllerMap = await _controller.future; - final LatLngBounds bounds = await controllerMap.getVisibleRegion(); - final LatLng mapViewCenter = LatLng( - (bounds.southwest.latitude + bounds.northeast.latitude) / 2, - (bounds.southwest.longitude + bounds.northeast.longitude) / 2, - ); - - final AnimationController controller = AnimationController( - duration: const Duration(milliseconds: 300), - vsync: this, - ); - - final Animation animation = CurvedAnimation( - parent: controller, - curve: Curves.fastOutSlowIn, - ); - - final Tween latTween = Tween( - begin: mapViewCenter.latitude, - end: marker.position.latitude, - ); - final Tween lngTween = Tween( - begin: mapViewCenter.longitude, - end: marker.position.longitude, - ); - - controller.addListener(() { - moveMapViewCenterToCoordinates( - LatLng(latTween.evaluate(animation), lngTween.evaluate(animation)), - ); - }); - - const zoomLevel = 15.0; - final target = marker.position; - - const totalFrames = 10; - - for (var i = 0; i < totalFrames; i++) { - await Future.delayed(const Duration(milliseconds: 100)); - const zoomAmount = -0.1; - final newZoom = zoomLevel + zoomAmount * (i + 1); - final updatedCamera = CameraUpdate.newLatLngZoom(target, newZoom); - controllerMap.animateCamera(updatedCamera); - } - - await Future.delayed(const Duration(seconds: 2)); - } - } - - void moveMapViewCenterToCoordinates(final LatLng coordinates) { - _controller.future.then((controller) { - controller.animateCamera( - CameraUpdate.newLatLng( - LatLng(coordinates.latitude, coordinates.longitude), - ), - ); - }); - } - - void _moveToNextMarker(Location location) async { - if (appState.experianceType == "Virtual") { - final nextMarker = Marker( - markerId: MarkerId(location.id.toString()), - icon: BitmapDescriptor.defaultMarker, - position: location.coords, - infoWindow: InfoWindow( - title: location.name, - ), - ); - - await moveToMarker(nextMarker); - _showVideoModal(); - } - } - - void _showVideoModal() { - showDialog( - context: context, - barrierColor: Colors.black.withOpacity(0.5), - builder: (BuildContext context) { - return VideoModalContent( - togglePanel: widget.togglePanel, - currentLocation: appState.currentLocation); - }, - ); - } - - @override - Widget build(BuildContext context) { - appState = context.watch(); - return Scaffold( - body: GoogleMap( - padding: const EdgeInsets.only(left: 16.0, bottom: 100.0), - mapType: MapType.normal, - initialCameraPosition: CameraPosition( - target: locations.last.coords, - zoom: 11.4, - ), - markers: Set.of( - locations.map((location) => Marker( - markerId: MarkerId(location.id.toString()), - position: location.coords, - infoWindow: InfoWindow( - title: location.name, - snippet: location.descr, - ), - onTap: () { - if (appState.experianceType == "Explore") { - appState.changeCurrentLocation(location); - widget.togglePanel(0.5); - } - }, - )), - ), - onMapCreated: (GoogleMapController controller) { - controller.setMapStyle(mapTheme); - _controller.complete(controller); - }, - ), - ); - } -} +// import 'dart:async'; +// import 'package:flick_video_player/flick_video_player.dart'; +// import 'package:my_app/additionals/locations_list.dart'; +// import 'package:my_app/main.dart'; +// import 'package:my_app/widgets/video_modal.dart'; +// import 'package:flutter/material.dart'; +// import 'package:google_maps_flutter/google_maps_flutter.dart'; +// import 'package:my_app/additionals/location.dart'; +// import 'package:provider/provider.dart'; + +// class MapGoogle extends StatefulWidget { +// final void Function(double position) togglePanel; + +// const MapGoogle({ +// Key? key, +// required this.togglePanel, +// }) : super(key: key); + +// @override +// State createState() => MapGoogleState(); +// } + +// class MapGoogleState extends State with TickerProviderStateMixin { +// late AppState appState; +// String mapTheme = ''; +// late FlickManager flickManager; +// final Completer _controller = +// Completer(); +// final List locations = LocationList.locations; +// Location? _previousLocation; + +// @override +// void initState() { +// super.initState(); + +// DefaultAssetBundle.of(context) +// .loadString('assets/maptheme/dark_theme.json') +// .then((value) => mapTheme = value); +// appState = Provider.of(context, listen: false); +// } + +// @override +// void didChangeDependencies() { +// super.didChangeDependencies(); +// final currentLocation = appState.currentLocation; + +// if (_previousLocation != currentLocation && +// currentLocation != null && +// appState.experianceType == "Virtual") { +// _previousLocation = currentLocation; +// _moveToNextMarker(currentLocation); +// } +// } + +// Future moveToMarker(Marker marker) async { +// if (appState.experianceType == "Virtual") { +// final GoogleMapController controllerMap = await _controller.future; +// final LatLngBounds bounds = await controllerMap.getVisibleRegion(); +// final LatLng mapViewCenter = LatLng( +// (bounds.southwest.latitude + bounds.northeast.latitude) / 2, +// (bounds.southwest.longitude + bounds.northeast.longitude) / 2, +// ); + +// final AnimationController controller = AnimationController( +// duration: const Duration(milliseconds: 300), +// vsync: this, +// ); + +// final Animation animation = CurvedAnimation( +// parent: controller, +// curve: Curves.fastOutSlowIn, +// ); + +// final Tween latTween = Tween( +// begin: mapViewCenter.latitude, +// end: marker.position.latitude, +// ); +// final Tween lngTween = Tween( +// begin: mapViewCenter.longitude, +// end: marker.position.longitude, +// ); + +// controller.addListener(() { +// moveMapViewCenterToCoordinates( +// LatLng(latTween.evaluate(animation), lngTween.evaluate(animation)), +// ); +// }); + +// const zoomLevel = 15.0; +// final target = marker.position; + +// const totalFrames = 10; + +// for (var i = 0; i < totalFrames; i++) { +// await Future.delayed(const Duration(milliseconds: 100)); +// const zoomAmount = -0.1; +// final newZoom = zoomLevel + zoomAmount * (i + 1); +// final updatedCamera = CameraUpdate.newLatLngZoom(target, newZoom); +// controllerMap.animateCamera(updatedCamera); +// } + +// await Future.delayed(const Duration(seconds: 2)); +// } +// } + +// void moveMapViewCenterToCoordinates(final LatLng coordinates) { +// _controller.future.then((controller) { +// controller.animateCamera( +// CameraUpdate.newLatLng( +// LatLng(coordinates.latitude, coordinates.longitude), +// ), +// ); +// }); +// } + +// void _moveToNextMarker(Location location) async { +// if (appState.experianceType == "Virtual") { +// final nextMarker = Marker( +// markerId: MarkerId(location.id.toString()), +// icon: BitmapDescriptor.defaultMarker, +// position: location.coords, +// infoWindow: InfoWindow( +// title: location.name, +// ), +// ); + +// await moveToMarker(nextMarker); +// _showVideoModal(); +// } +// } + +// void _showVideoModal() { +// showDialog( +// context: context, +// barrierColor: Colors.black.withOpacity(0.5), +// builder: (BuildContext context) { +// return VideoModalContent( +// togglePanel: widget.togglePanel, +// currentLocation: appState.currentLocation); +// }, +// ); +// } + +// @override +// Widget build(BuildContext context) { +// appState = context.watch(); +// return Scaffold( +// body: GoogleMap( +// padding: const EdgeInsets.only(left: 16.0, bottom: 100.0), +// mapType: MapType.normal, +// initialCameraPosition: CameraPosition( +// target: locations.last.coords, +// zoom: 11.4, +// ), +// markers: Set.of( +// locations.map((location) => Marker( +// markerId: MarkerId(location.id.toString()), +// position: location.coords, +// infoWindow: InfoWindow( +// title: location.name, +// snippet: location.descr, +// ), +// onTap: () { +// if (appState.experianceType == "Explore") { +// appState.changeCurrentLocation(location); +// widget.togglePanel(0.5); +// } +// }, +// )), +// ), +// onMapCreated: (GoogleMapController controller) { +// controller.setMapStyle(mapTheme); +// _controller.complete(controller); +// }, +// ), +// ); +// } +// } diff --git a/pubspec.lock b/pubspec.lock index 7e91130..e65aefe 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1,6 +1,14 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: + archive: + dependency: transitive + description: + name: archive + sha256: "22600aa1e926be775fa5fe7e6894e7fb3df9efda8891c73f70fb3262399a432d" + url: "https://pub.dev" + source: hosted + version: "3.4.10" async: dependency: transitive description: @@ -113,6 +121,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.18.0" + convert: + dependency: transitive + description: + name: convert + sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" + url: "https://pub.dev" + source: hosted + version: "3.1.1" crypto: dependency: transitive description: @@ -182,6 +198,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.1" + flutter_map: + dependency: "direct main" + description: + name: flutter_map + sha256: "52c65a977daae42f9aae6748418dd1535eaf27186e9bac9bf431843082bc75a3" + url: "https://pub.dev" + source: hosted + version: "4.0.0" flutter_plugin_android_lifecycle: dependency: transitive description: @@ -264,6 +288,22 @@ packages: url: "https://pub.dev" source: hosted version: "4.0.2" + image: + dependency: transitive + description: + name: image + sha256: "8e9d133755c3e84c73288363e6343157c383a0c6c56fc51afcc5d4d7180306d6" + url: "https://pub.dev" + source: hosted + version: "3.3.0" + intl: + dependency: transitive + description: + name: intl + sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf + url: "https://pub.dev" + source: hosted + version: "0.19.0" js: dependency: transitive description: @@ -272,6 +312,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.6.5" + latlong2: + dependency: "direct main" + description: + name: latlong2 + sha256: "08ef7282ba9f76e8495e49e2dc4d653015ac929dce5f92b375a415d30b407ea0" + url: "https://pub.dev" + source: hosted + version: "0.8.2" lints: dependency: transitive description: @@ -280,6 +328,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.1" + lists: + dependency: transitive + description: + name: lists + sha256: "4ca5c19ae4350de036a7e996cdd1ee39c93ac0a2b840f4915459b7d0a7d4ab27" + url: "https://pub.dev" + source: hosted + version: "1.0.1" logging: dependency: transitive description: @@ -288,6 +344,38 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.0" + mapbox_gl: + dependency: "direct main" + description: + name: mapbox_gl + sha256: d78907338ff232e3cf6c1d6dba45e6a8814069496fd352e49bb1967d498f09af + url: "https://pub.dev" + source: hosted + version: "0.16.0" + mapbox_gl_dart: + dependency: transitive + description: + name: mapbox_gl_dart + sha256: de6d03718e5eb05c9eb1ddaae7f0383b28acb5afa16405e1deed7ff04dd34f3d + url: "https://pub.dev" + source: hosted + version: "0.2.1" + mapbox_gl_platform_interface: + dependency: transitive + description: + name: mapbox_gl_platform_interface + sha256: b7c1490b022e650afd20412bdf8ae45a1897118b7ce6049ef6c42df09193d4b2 + url: "https://pub.dev" + source: hosted + version: "0.16.0" + mapbox_gl_web: + dependency: transitive + description: + name: mapbox_gl_web + sha256: e77113bf95a4f321ff44938232517e0f2725aae991f0b283af1afaa7e7a58aca + url: "https://pub.dev" + source: hosted + version: "0.16.0" matcher: dependency: transitive description: @@ -312,6 +400,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.10.0" + mgrs_dart: + dependency: transitive + description: + name: mgrs_dart + sha256: fb89ae62f05fa0bb90f70c31fc870bcbcfd516c843fb554452ab3396f78586f7 + url: "https://pub.dev" + source: hosted + version: "2.0.0" nested: dependency: transitive description: @@ -376,6 +472,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.6" + petitparser: + dependency: transitive + description: + name: petitparser + sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27 + url: "https://pub.dev" + source: hosted + version: "6.0.2" platform: dependency: transitive description: @@ -392,6 +496,22 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.4" + pointycastle: + dependency: transitive + description: + name: pointycastle + sha256: "43ac87de6e10afabc85c445745a7b799e04de84cebaa4fd7bf55a5e1e9604d29" + url: "https://pub.dev" + source: hosted + version: "3.7.4" + polylabel: + dependency: transitive + description: + name: polylabel + sha256: "41b9099afb2aa6c1730bdd8a0fab1400d287694ec7615dd8516935fa3144214b" + url: "https://pub.dev" + source: hosted + version: "1.0.1" process: dependency: transitive description: @@ -400,6 +520,14 @@ packages: url: "https://pub.dev" source: hosted version: "4.2.4" + proj4dart: + dependency: transitive + description: + name: proj4dart + sha256: c8a659ac9b6864aa47c171e78d41bbe6f5e1d7bd790a5814249e6b68bc44324e + url: "https://pub.dev" + source: hosted + version: "2.1.0" provider: dependency: "direct main" description: @@ -493,6 +621,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.6.1" + tuple: + dependency: transitive + description: + name: tuple + sha256: a97ce2013f240b2f3807bcbaf218765b6f301c3eff91092bcfa23a039e7dd151 + url: "https://pub.dev" + source: hosted + version: "2.0.2" typed_data: dependency: transitive description: @@ -501,6 +637,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.1" + unicode: + dependency: transitive + description: + name: unicode + sha256: "0f69e46593d65245774d4f17125c6084d2c20b4e473a983f6e21b7d7762218f1" + url: "https://pub.dev" + source: hosted + version: "0.3.1" universal_html: dependency: transitive description: @@ -629,6 +773,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.1.4" + wkt_parser: + dependency: transitive + description: + name: wkt_parser + sha256: "8a555fc60de3116c00aad67891bcab20f81a958e4219cc106e3c037aa3937f13" + url: "https://pub.dev" + source: hosted + version: "2.0.0" xdg_directories: dependency: transitive description: @@ -637,6 +789,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.0" + xml: + dependency: transitive + description: + name: xml + sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226 + url: "https://pub.dev" + source: hosted + version: "6.5.0" sdks: - dart: ">=3.2.0-194.0.dev <4.0.0" + dart: ">=3.2.0 <4.0.0" flutter: ">=3.13.0" diff --git a/pubspec.yaml b/pubspec.yaml index f8f073e..797b956 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -39,10 +39,13 @@ dependencies: carousel_slider: ^4.2.1 go_router: ^13.2.0 provider: ^6.1.2 + flutter_map: ^4.0.0 + mapbox_gl: ^0.16.0 # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.2 + latlong2: ^0.8.2 dev_dependencies: flutter_test: