diff --git a/lib/components/MapKmlElement.dart b/lib/components/MapKmlElement.dart index 62288be..5ecdda7 100644 --- a/lib/components/MapKmlElement.dart +++ b/lib/components/MapKmlElement.dart @@ -10,7 +10,7 @@ import 'package:super_liquid_galaxy_controller/data_class/kml_element.dart'; import 'package:super_liquid_galaxy_controller/data_class/map_position.dart'; import 'package:super_liquid_galaxy_controller/screens/map_kml_fullscreen.dart'; import 'package:super_liquid_galaxy_controller/utils/galaxy_colors.dart'; -import 'package:super_liquid_galaxy_controller/utils/map_movement_controller.dart'; +import 'package:super_liquid_galaxy_controller/controllers/map_movement_controller.dart'; class Mapkmlelement extends StatefulWidget { Mapkmlelement( diff --git a/lib/components/apimanager_block.dart b/lib/components/apimanager_block.dart index ca08082..2f655ce 100644 --- a/lib/components/apimanager_block.dart +++ b/lib/components/apimanager_block.dart @@ -1,6 +1,6 @@ import 'dart:ui'; import 'package:flutter/material.dart'; -import 'package:super_liquid_galaxy_controller/utils/api_manager.dart'; +import 'package:super_liquid_galaxy_controller/controllers/api_manager.dart'; import '../generated/assets.dart'; import 'custom_dialog.dart'; import 'galaxytextfield.dart'; diff --git a/lib/components/autocomplete_locationfield.dart b/lib/components/autocomplete_locationfield.dart index cad8ff8..b6f9b91 100644 --- a/lib/components/autocomplete_locationfield.dart +++ b/lib/components/autocomplete_locationfield.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:super_liquid_galaxy_controller/utils/autocomplete_controller.dart'; +import 'package:super_liquid_galaxy_controller/controllers/autocomplete_controller.dart'; import 'package:super_liquid_galaxy_controller/utils/galaxy_colors.dart'; import '../data_class/place_suggestion_response.dart'; diff --git a/lib/components/location_selector.dart b/lib/components/location_selector.dart index c1ce711..97ca16f 100644 --- a/lib/components/location_selector.dart +++ b/lib/components/location_selector.dart @@ -10,7 +10,7 @@ import 'package:super_liquid_galaxy_controller/data_class/country_data.dart'; import 'package:super_liquid_galaxy_controller/screens/location_picker.dart'; import 'package:super_liquid_galaxy_controller/utils/galaxy_colors.dart'; import 'package:geocoding/geocoding.dart'; -import 'package:super_liquid_galaxy_controller/utils/tour_controller.dart'; +import 'package:super_liquid_galaxy_controller/controllers/tour_controller.dart'; import '../generated/assets.dart'; class LocationSelector extends StatefulWidget { diff --git a/lib/utils/api_manager.dart b/lib/controllers/api_manager.dart similarity index 87% rename from lib/utils/api_manager.dart rename to lib/controllers/api_manager.dart index dd60b9b..f61d979 100644 --- a/lib/utils/api_manager.dart +++ b/lib/controllers/api_manager.dart @@ -88,6 +88,23 @@ class ApiManager extends getx.GetxController { return response; } + + + Future getNearbyPlaces(Coordinates point) async { + await _connectApi(2); + var response = await _apiClient.get(placesEndPoint, queryParameters: { + 'filter': 'circle:${point.longitude},${point.latitude},50000', + 'bias':'proximity:${point.longitude},${point.latitude}', + 'apiKey': _placesApiKey.trim(), + 'categories': 'commercial,tourism,entertainment,leisure,building', + 'limit': '50' + }); + if (response.statusCode != 200) { + handleError(response); + } + return response; + } + Future getPlaces(String id, String categories) async { await _connectApi(2); var response = await _apiClient.get(placesEndPoint, queryParameters: { @@ -306,6 +323,33 @@ class ApiManager extends getx.GetxController { return (kml:'',obj: null,places:[]); } + Future<({String kml,pr.PlaceResponse? obj,List places})> tryPlaceResponseForCoordinates( + Coordinates coords) async { + Response places = await getNearbyPlaces(coords); + if (places.statusCode != 200) { + return (kml:'',obj: null,places:[]); + } + var placeObj = pr.PlaceResponse.fromJson(places.data); + //print(placeObj); + if (placeObj.features!=null && placeObj.features!.isNotEmpty) { + var list = placeObj.features; + List coordinates = []; + for (final feature in list!) { + try { + // var name = (feature.properties!.name != null)?feature.properties!.name!.replaceAll('&', 'and'):feature.properties!.addressLine1!; + coordinates.add(getPlaceInfo(feature)); + } catch (e) { + print(e); + print(feature); + } + } + String kml = KMLGenerator.addPlaces(coordinates); + //getx.Get.to(() => TestScreen(kml: KMLGenerator.generateKml('69', kml))); + return (kml:kml,obj:placeObj,places: coordinates); + } + return (kml:'',obj: null,places:[]); + } + PlaceInfo getPlaceInfo(pr.Features feature) { var name = (feature.properties!.name != null)?feature.properties!.name!.replaceAll('&', 'and'):feature.properties!.addressLine1!; var category = 'default'; @@ -328,4 +372,5 @@ class ApiManager extends getx.GetxController { } + } diff --git a/lib/utils/autocomplete_controller.dart b/lib/controllers/autocomplete_controller.dart similarity index 97% rename from lib/utils/autocomplete_controller.dart rename to lib/controllers/autocomplete_controller.dart index 124ad2c..9dda5f0 100644 --- a/lib/utils/autocomplete_controller.dart +++ b/lib/controllers/autocomplete_controller.dart @@ -1,7 +1,7 @@ import 'dart:async'; import 'package:super_liquid_galaxy_controller/data_class/place_suggestion_response.dart'; -import 'package:super_liquid_galaxy_controller/utils/api_manager.dart'; +import 'package:super_liquid_galaxy_controller/controllers/api_manager.dart'; import 'package:get/get.dart'; const Duration debounceDuration = Duration(milliseconds: 250); diff --git a/lib/utils/lg_connection.dart b/lib/controllers/lg_connection.dart similarity index 87% rename from lib/utils/lg_connection.dart rename to lib/controllers/lg_connection.dart index 38ad4d3..11cc61c 100644 --- a/lib/utils/lg_connection.dart +++ b/lib/controllers/lg_connection.dart @@ -1,5 +1,6 @@ import 'dart:io'; - +import '../utils/balloongenerator.dart'; +import '../utils/constants.dart'; import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:dartssh2/dartssh2.dart'; @@ -306,6 +307,43 @@ fi } } + Future cleanBalloon() async { + try { + if(_client==null) + { + await reConnectToLG(); + if(isConnected.value==false) { + return false; + } + } + + await _client?.run( + "echo '${BalloonGenerator.blankBalloon()}' > /var/www/html/kml/slave_${int.parse(_numberOfRigs).rightMostRig}.kml"); + return true; + } catch (error) { + print(error); + return false; + } + } + + Future flyToInstantWithoutSaving(MapPosition position) async { + try { + if(_client==null) + { + await reConnectToLG(); + if(isConnected.value==false) { + return false; + } + } + await _client?.run( + 'echo "flytoview=${KMLGenerator.lookAtLinearInstant(position)}" > /tmp/query.txt'); + return true; + } catch (error) { + print(error); + return false; + } + } + Future moveTo(MapPosition position) async { print(position); @@ -353,5 +391,22 @@ fi print("error : $e"); } } + Future flyToOrbit(MapPosition position) async { + try { + if(_client==null) + { + await reConnectToLG(); + if(isConnected.value==false) { + return false; + } + } + await _client?.run( + 'echo "flytoview=${KMLGenerator.orbitLookAtLinear(position)}" > /tmp/query.txt'); + return true; + } catch (error) { + print(error); + return false; + } + } } \ No newline at end of file diff --git a/lib/utils/map_movement_controller.dart b/lib/controllers/map_movement_controller.dart similarity index 100% rename from lib/utils/map_movement_controller.dart rename to lib/controllers/map_movement_controller.dart diff --git a/lib/controllers/poi_controller.dart b/lib/controllers/poi_controller.dart new file mode 100644 index 0000000..2e5aa7a --- /dev/null +++ b/lib/controllers/poi_controller.dart @@ -0,0 +1,272 @@ +import 'dart:io'; +import 'dart:math'; +import 'package:google_maps_flutter/google_maps_flutter.dart' as maps; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_tts/flutter_tts.dart'; +import 'package:get/get.dart'; +import 'package:super_liquid_galaxy_controller/data_class/coordinate.dart'; +import 'package:super_liquid_galaxy_controller/data_class/place_info.dart'; +import 'package:super_liquid_galaxy_controller/screens/test.dart'; +import 'package:super_liquid_galaxy_controller/utils/constants.dart'; +import 'package:super_liquid_galaxy_controller/utils/wikidatafetcher.dart'; + +import '../data_class/map_position.dart'; +import '../utils/geo_utils.dart'; +import '../utils/kmlgenerator.dart'; +import 'api_manager.dart'; +import 'lg_connection.dart'; + +class PoiController extends GetxController { + late ApiManager apiClient; + late LGConnection connectionClient; + late WikiDataFetcher dataFetcher; + //late PlaceInfo place; + + var descriptionIsLoading = false.obs; + var descriptionIsError = false.obs; + var imageIsLoading = false.obs; + var imageIsError = false.obs; + var isOrbit = false.obs; + var isVoicing = false.obs; + + var description = ''.obs; + var imageLink = ''.obs; + var poiList = [].obs; + var place = PlaceInfo(coordinate: Coordinates(latitude: 0.0, longitude: 0.0), label: "Loading...", address: "Loading..", category: "Loading...", name: "Loading....").obs; + + FlutterTts flutterTts = FlutterTts(); + + @override + void onInit() { + apiClient = Get.find(); + connectionClient = Get.find(); + dataFetcher = WikiDataFetcher(); + //flutterTts.setLanguage("en-US"); + flutterTts.setCompletionHandler((){ + print("completed"); + isVoicing.value = false; + }); + super.onInit(); + } + + void setInfo(PlaceInfo pl) { + place.value = pl; + //screenSize = s; + //context = con; + description.value = place.value.description ?? ''; + imageLink.value = place.value.imageLink ?? ''; + poiList.clear(); + } + + void fetchAllInfo() async { + await fetchDescription(); + await loadImage(); + await fetchNearbyPois(); + await setKML(); + await zoomToLocation(); + } + + void voiceButtonPressed() async { + if (isVoicing.value) { + isVoicing.value = false; + flutterTts.stop(); + } else { + isVoicing.value = true; + print("playing"); + String text; + + if (description.value.indexOf('\t') != -1) { + text = description.value.substring( + 0, + min(description.value.indexOf('\t'), + min(1500, description.value.length - 1))); + } else { + text = description.value.substring( + 0, + + min(1500, description.value.length - 1)); + } + print(text); + var state = await flutterTts.speak(text); + + + print("started $state"); + + await flutterTts.awaitSpeakCompletion(true); + print("completed"); + isVoicing.value = false; + } + } + + Future fetchDescription() async { + descriptionIsLoading.value = true; + descriptionIsError.value = false; + dataFetcher.setData(place.value); + try { + description.value = await dataFetcher.getInfo() ?? "Loading...."; + if (description.value == "Loading....") { + throw Exception("No Data Found"); + } + place.value.description = description.value; + descriptionIsLoading.value = false; + descriptionIsError.value = false; + } catch (e) { + descriptionIsLoading.value = false; + descriptionIsError.value = true; + } + } + + Future loadImage() async { + imageIsLoading.value = true; + imageIsError.value = false; + try { + imageLink.value = await dataFetcher.getImages() ?? ''; + place.value.imageLink = imageLink.value; + if (imageLink.value == "") { + throw Exception("No Data Found"); + } + imageIsLoading.value = false; + imageIsError.value = false; + } catch (e) { + imageIsLoading.value = false; + imageIsError.value = true; + } + print("masterLink: ${imageLink.value}"); + } + + Future fetchNearbyPois() async { + try { + var response = await apiClient.tryPlaceResponseForCoordinates( + place.value.coordinate); + print(response.places); + print(response.obj); + print(response.kml); + if (response.places.isNotEmpty) { + poiList.clear(); + poiList.addAll(response.places); + } + } + catch(error) + { + if(!Get.isSnackbarOpen) + { + Get.showSnackbar(GetSnackBar( + backgroundColor: Colors.red.shade300, + title: "Network Error", + message: "Error: $error", + isDismissible: true, + duration: 2.seconds, + )); + } + fetchNearbyPois(); + } + } + + /*zoomToBoundsLocation() async + { + print("bounds"); + List points= []; + points.add(place.value.coordinate.toLatLngMap(place.value.coordinate)); + for(final point in poiList) + { + points.add(point.coordinate.toLatLngMap(point.coordinate)); + } + MapPosition position = + MapPosition.fromCameraPosition( + GeoUtils.getBoundsZoomLevel( + points, + Get.context!.size!)); + position.updateFromCoordinates(place.value.coordinate); + await connectionClient.flyToInstantWithoutSaving(position); + await connectionClient.cleanBalloon(); + print(position); + }*/ + + zoomToLocation() async { + print("loc"); + MapPosition position = + MapPosition.fromCameraPosition( + GeoUtils.getBoundsZoomLevel( + [place.value.coordinate.toLatLngMap(place.value.coordinate)], + Get.context!.size!)); + + //String kml= KMLGenerator.generateKml('69', KMLGenerator.orbitLookAtLinear(position)); + //Get.to(()=> TestScreen(kml: kml)); + await connectionClient.flyToInstantWithoutSaving(position); + await connectionClient.cleanBalloon(); + print(position); + } + + startOrbit(MapPosition position) async + { + /*MapPosition position = + MapPosition.fromCameraPosition( + GeoUtils.getBoundsZoomLevel( + [place.value.coordinate.toLatLngMap(place.value.coordinate)], + MediaQuery.of(context).size));*/ + //await Future.delayed(const Duration(milliseconds: 8000)); + position.tilt = 60.0; + for (int i = 0; i <= 360; i += 17) { + if(!isOrbit.value) + { + return; + } + //print(MapPosition(latitude: position.latitude, longitude: position.longitude, bearing: i.toDouble(), tilt: position.tilt, zoom: position.zoom)); + connectionClient.flyToOrbit( + MapPosition(latitude: position.latitude, longitude: position.longitude, bearing: i.toDouble(), tilt: position.tilt, zoom: position.zoom)); + await Future.delayed(const Duration(milliseconds: 1000)); + } + + startOrbit(position); + } + + void orbitButtonPressed() async { + isOrbit.value = !isOrbit.value; + if(isOrbit.value) + { + await zoomToLocation(); + MapPosition position = + MapPosition.fromCameraPosition( + GeoUtils.getBoundsZoomLevel( + [place.value.coordinate.toLatLngMap(place.value.coordinate)], + Get.context!.size!)); + print("sizes: ${Get.context!.size!}"); + print("sizes: ${Get.size}"); + + await startOrbit(position); + } + else{ + await zoomToLocation(); + } + + } + + setKML() { + String kml = KMLGenerator.generateKml('69', KMLGenerator.getPOIKML(place.value, poiList)); + runKml(kml); + } + + Future runKml(String kmlResponse) async { + + //print("tapped"); + String filename = generateRandomString(7); + await connectionClient.connectToLG(); + if(!connectionClient.isConnected.value) + return; + File? file = await connectionClient.makeFile(filename, + kmlResponse); + print("made successfully"); + await connectionClient.kmlFileUpload( + file!, filename); + print("uploaded successfully"); + await connectionClient.runKml(filename); + } + String generateRandomString(int len) { + var r = Random.secure(); + const _chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz_'; + return List.generate(len, (index) => _chars[r.nextInt(_chars.length)]) + .join(); + } + +} diff --git a/lib/utils/speech_controller.dart b/lib/controllers/speech_controller.dart similarity index 98% rename from lib/utils/speech_controller.dart rename to lib/controllers/speech_controller.dart index 0cf295b..89883ee 100644 --- a/lib/utils/speech_controller.dart +++ b/lib/controllers/speech_controller.dart @@ -2,7 +2,7 @@ import 'dart:collection'; import 'package:get/get.dart'; import 'package:speech_to_text/speech_to_text.dart' as stt; -import 'package:super_liquid_galaxy_controller/utils/map_movement_controller.dart'; +import 'package:super_liquid_galaxy_controller/controllers/map_movement_controller.dart'; class SpeechController extends GetxController { var isListening = false.obs; diff --git a/lib/utils/tour_controller.dart b/lib/controllers/tour_controller.dart similarity index 93% rename from lib/utils/tour_controller.dart rename to lib/controllers/tour_controller.dart index 31b4b6a..50782bc 100644 --- a/lib/utils/tour_controller.dart +++ b/lib/controllers/tour_controller.dart @@ -9,15 +9,15 @@ import 'package:super_liquid_galaxy_controller/data_class/map_position.dart'; import 'package:super_liquid_galaxy_controller/data_class/place_details_response.dart'; import 'package:super_liquid_galaxy_controller/data_class/place_info.dart'; import 'package:super_liquid_galaxy_controller/data_class/place_response.dart'; -import 'package:super_liquid_galaxy_controller/utils/api_manager.dart'; +import 'package:super_liquid_galaxy_controller/controllers/api_manager.dart'; import 'package:super_liquid_galaxy_controller/utils/geo_utils.dart'; -import 'package:super_liquid_galaxy_controller/utils/lg_connection.dart'; +import 'package:super_liquid_galaxy_controller/controllers/lg_connection.dart'; import 'package:super_liquid_galaxy_controller/utils/wikidatafetcher.dart'; import '../data_class/coordinate.dart'; import '../data_class/kml_element.dart'; import '../screens/test.dart'; -import 'kmlgenerator.dart'; +import '../utils/kmlgenerator.dart'; class TourController extends getx.GetxController { late ApiManager apiClient; @@ -26,6 +26,8 @@ class TourController extends getx.GetxController { PlaceDetailsResponse? boundaryPlace; var label = ''.obs; PlaceResponse? places; + String kml = ""; + MapPosition? lookAtPosition; List masterList = []; getx.RxList placeList = [].obs; final isLoading = false.obs; @@ -114,12 +116,13 @@ class TourController extends getx.GetxController { if (boundaryPlace != null) { kmlResponse = KMLGenerator.generateKml('69', kmlResponse); } - + kml = kmlResponse; //getx.Get.to(()=>TestScreen(kml: kmlResponse)); await runKml(kmlResponse); if (context != null) { var position = MapPosition.fromCameraPosition( GeoUtils.getBoundsZoomLevel(coords, getScreenSize(context!))); + lookAtPosition = position; await connectionClient.moveTo(position); } adjustPlaceMarks(); @@ -154,6 +157,11 @@ class TourController extends getx.GetxController { .join(); } + Future zoomToLocation(MapPosition position) async { + print("Location state level"); + await connectionClient.moveTo(position); + } + void adjustPlaceMarks() { const maxLength = 20; diff --git a/lib/main.dart b/lib/main.dart index 2d68b9b..f5b1712 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -8,12 +8,12 @@ import 'package:super_liquid_galaxy_controller/screens/dashboard.dart'; import 'package:super_liquid_galaxy_controller/screens/maps_controller.dart'; import 'package:super_liquid_galaxy_controller/screens/place_view.dart'; import 'package:super_liquid_galaxy_controller/screens/splashscreen.dart'; -import 'package:super_liquid_galaxy_controller/utils/api_manager.dart'; -import 'package:super_liquid_galaxy_controller/utils/lg_connection.dart'; -import 'package:super_liquid_galaxy_controller/utils/map_movement_controller.dart'; -import 'package:super_liquid_galaxy_controller/utils/poi_controller.dart'; -import 'package:super_liquid_galaxy_controller/utils/speech_controller.dart'; -import 'package:super_liquid_galaxy_controller/utils/tour_controller.dart'; +import 'package:super_liquid_galaxy_controller/controllers/api_manager.dart'; +import 'package:super_liquid_galaxy_controller/controllers/lg_connection.dart'; +import 'package:super_liquid_galaxy_controller/controllers/map_movement_controller.dart'; +import 'package:super_liquid_galaxy_controller/controllers/poi_controller.dart'; +import 'package:super_liquid_galaxy_controller/controllers/speech_controller.dart'; +import 'package:super_liquid_galaxy_controller/controllers/tour_controller.dart'; import 'package:super_liquid_galaxy_controller/utils/wikidatafetcher.dart'; AndroidMapRenderer mapRenderer = AndroidMapRenderer.platformDefault; diff --git a/lib/screens/dashboard.dart b/lib/screens/dashboard.dart index 40de834..a4b57a5 100644 --- a/lib/screens/dashboard.dart +++ b/lib/screens/dashboard.dart @@ -7,8 +7,8 @@ import 'package:super_liquid_galaxy_controller/components/navisland.dart'; import 'package:super_liquid_galaxy_controller/components/planet_selector.dart'; import 'package:super_liquid_galaxy_controller/generated/assets.dart'; import 'package:super_liquid_galaxy_controller/screens/settings.dart'; -import 'package:super_liquid_galaxy_controller/utils/api_manager.dart'; -import 'package:super_liquid_galaxy_controller/utils/lg_connection.dart'; +import 'package:super_liquid_galaxy_controller/controllers/api_manager.dart'; +import 'package:super_liquid_galaxy_controller/controllers/lg_connection.dart'; import 'package:lottie/lottie.dart'; import '../components/connection_flag.dart'; diff --git a/lib/screens/kml_builder.dart b/lib/screens/kml_builder.dart index 41f0777..f6fbab4 100644 --- a/lib/screens/kml_builder.dart +++ b/lib/screens/kml_builder.dart @@ -19,12 +19,12 @@ import 'package:super_liquid_galaxy_controller/screens/test.dart'; import 'package:super_liquid_galaxy_controller/utils/galaxy_colors.dart'; import 'package:super_liquid_galaxy_controller/utils/geo_utils.dart'; import 'package:super_liquid_galaxy_controller/utils/kmlgenerator.dart'; -import 'package:super_liquid_galaxy_controller/utils/lg_connection.dart'; +import 'package:super_liquid_galaxy_controller/controllers/lg_connection.dart'; import '../data_class/kml_element.dart'; import '../data_class/map_position.dart'; import '../generated/assets.dart'; -import '../utils/map_movement_controller.dart'; +import '../controllers/map_movement_controller.dart'; class KmlUploader extends StatefulWidget { const KmlUploader({super.key}); diff --git a/lib/screens/map_kml_fullscreen.dart b/lib/screens/map_kml_fullscreen.dart index d352d61..0b8c9a5 100644 --- a/lib/screens/map_kml_fullscreen.dart +++ b/lib/screens/map_kml_fullscreen.dart @@ -4,7 +4,7 @@ import 'package:super_liquid_galaxy_controller/components/MapKmlElement.dart'; import 'package:super_liquid_galaxy_controller/data_class/kml_element.dart'; import '../data_class/map_position.dart'; -import '../utils/map_movement_controller.dart'; +import '../controllers/map_movement_controller.dart'; class MapKmlFullscreen extends StatefulWidget { MapKmlFullscreen( diff --git a/lib/screens/maps_controller.dart b/lib/screens/maps_controller.dart index ed17080..4faa1e0 100644 --- a/lib/screens/maps_controller.dart +++ b/lib/screens/maps_controller.dart @@ -14,10 +14,10 @@ import 'package:super_liquid_galaxy_controller/data_class/coordinate.dart'; import 'package:super_liquid_galaxy_controller/data_class/map_position.dart'; import 'package:super_liquid_galaxy_controller/data_class/place_suggestion_response.dart'; import 'package:super_liquid_galaxy_controller/generated/assets.dart'; -import 'package:super_liquid_galaxy_controller/utils/autocomplete_controller.dart'; -import 'package:super_liquid_galaxy_controller/utils/lg_connection.dart'; -import 'package:super_liquid_galaxy_controller/utils/map_movement_controller.dart'; -import 'package:super_liquid_galaxy_controller/utils/speech_controller.dart'; +import 'package:super_liquid_galaxy_controller/controllers/autocomplete_controller.dart'; +import 'package:super_liquid_galaxy_controller/controllers/lg_connection.dart'; +import 'package:super_liquid_galaxy_controller/controllers/map_movement_controller.dart'; +import 'package:super_liquid_galaxy_controller/controllers/speech_controller.dart'; class MapController extends StatefulWidget { const MapController({super.key}); diff --git a/lib/screens/place_view.dart b/lib/screens/place_view.dart index 00f15af..f05cb47 100644 --- a/lib/screens/place_view.dart +++ b/lib/screens/place_view.dart @@ -5,9 +5,10 @@ import 'package:get/get.dart'; import 'package:lottie/lottie.dart'; import 'package:super_liquid_galaxy_controller/data_class/place_info.dart'; import 'package:super_liquid_galaxy_controller/utils/galaxy_colors.dart'; -import 'package:super_liquid_galaxy_controller/utils/poi_controller.dart'; +import 'package:super_liquid_galaxy_controller/controllers/poi_controller.dart'; import '../generated/assets.dart'; +import '../utils/constants.dart'; class PlaceView extends StatefulWidget { PlaceView({super.key, required this.place}); @@ -24,11 +25,15 @@ class _PlaceViewState extends State with TickerProviderStateMixin { late PoiController poiController; late AnimationController lottieController; late AnimationController voiceController; + late PlaceInfo currentPlace; @override void initState() { super.initState(); poiController = Get.find(); + poiController.isOrbit.value = false; + poiController.isVoicing.value = false; + currentPlace = widget.place; poiController.setInfo(widget.place); poiController.fetchAllInfo(); lottieController = AnimationController(vsync: this,duration: const Duration(seconds: 2)); @@ -40,6 +45,7 @@ class _PlaceViewState extends State with TickerProviderStateMixin { Widget build(BuildContext context) { screenHeight = MediaQuery.of(context).size.height; screenWidth = MediaQuery.of(context).size.width; + //print(MediaQuery.of(context).size); return SafeArea( child: Stack(children: [ Container( @@ -86,21 +92,23 @@ class _PlaceViewState extends State with TickerProviderStateMixin { child: FittedBox( fit: BoxFit.contain, alignment: Alignment.centerLeft, - child: Text( - widget.place.name, - style: const TextStyle( - shadows: [ - Shadow( - color: Colors.white, - offset: Offset(0, -8)) - ], - color: Colors.transparent, - fontSize: 40, - fontWeight: FontWeight.w400, - decoration: TextDecoration.underline, - decorationColor: Colors.white, - ), - ), + child: Obx((){ + return Text( + poiController.place.value.name, + style: const TextStyle( + shadows: [ + Shadow( + color: Colors.white, + offset: Offset(0, -8)) + ], + color: Colors.transparent, + fontSize: 40, + fontWeight: FontWeight.w400, + decoration: TextDecoration.underline, + decorationColor: Colors.white, + ), + ); + }), ), ), ), @@ -125,16 +133,18 @@ class _PlaceViewState extends State with TickerProviderStateMixin { child: Padding( padding: const EdgeInsets.symmetric( vertical: 2.0), - child: Text( - "ADDRESS: ${widget.place.address} \nLOCATION- Lat: ${widget.place.coordinate.latitude.toStringAsFixed(5)}, Long: ${widget.place.coordinate.longitude.toStringAsFixed(5)}", - overflow: TextOverflow.ellipsis, - style: const TextStyle( - color: Colors.white, - fontSize: 40, - fontWeight: FontWeight.w300, - decorationColor: Colors.white, - ), - ), + child: Obx((){ + return Text( + "ADDRESS: ${poiController.place.value.address} \nLOCATION- Lat: ${poiController.place.value.coordinate.latitude.toStringAsFixed(5)}, Long: ${poiController.place.value.coordinate.longitude.toStringAsFixed(5)}", + overflow: TextOverflow.ellipsis, + style: const TextStyle( + color: Colors.white, + fontSize: 40, + fontWeight: FontWeight.w300, + decorationColor: Colors.white, + ), + ); + }), ), ), ], @@ -187,8 +197,8 @@ class _PlaceViewState extends State with TickerProviderStateMixin { Radius.circular(50.0)), ), clipBehavior: Clip.hardEdge, - child: (poiController - .imageIsLoading.value + child: ((poiController + .imageIsLoading.value || poiController.imageLink.compareTo('')==0 )&& !poiController.imageIsError.value ? Lottie.asset( Assets.lottieImageloading, decoder: customDecoder, @@ -362,7 +372,98 @@ class _PlaceViewState extends State with TickerProviderStateMixin { child: Padding( padding: const EdgeInsets.fromLTRB( 12.0, 0.0, 12.0, 20.0), - child: Container(), + child: Obx( + (){ + print(poiController.poiList.length); + return Container( + child:(poiController.poiList.isNotEmpty)? ListView.builder(itemBuilder: (context,index){ + return Padding( + padding: const EdgeInsets.all(5.0), + child: Row( + mainAxisSize: MainAxisSize.max, + children: [ + Expanded(child: Material( + color: Colors.transparent, + child: InkWell( + radius: 20.0, + onTap: (){ + poiController.isOrbit.value = false; + poiController.isVoicing.value = false; + currentPlace = poiController.poiList[index]; + poiController.setInfo(poiController.poiList[index]); + poiController.fetchAllInfo(); + }, + child: Container( + height: screenHeight*0.07, + child: Row( + mainAxisSize: MainAxisSize.max, + children: [ + Expanded( + flex: 1, + child: Container( + child: FittedBox( + fit: BoxFit + .contain, + child: + Padding( + padding: + const EdgeInsets + .all( + 5.0), + child: + ImageIcon( + AssetImage( + Constants.tourismCategories.contains(poiController.poiList[index].category)?(Constants.assetPaths[Constants.tourismCategories.indexOf(poiController.poiList[index].category)]):Constants.assetPaths[Constants.assetPaths.length-1], ), + color: Colors + .white, + ), + )))), + Expanded( + flex: 6, + child: Container( + child: FittedBox( + fit: BoxFit + .contain, + child: + Padding( + padding: const EdgeInsets + .symmetric( + horizontal: + 8.0, + vertical: + 5.0), + child: Text( + poiController.poiList[index].name.length>12? "${poiController.poiList[index].name.substring(0,12)}...":poiController.poiList[index].name, + style: + const TextStyle( + color: Colors + .white, + ), + ), + )))) + ], + ), + ), + ), + )) + ], + ), + ); + }, + itemCount: poiController.poiList.length,):Center( + child: ( + Lottie.asset( + Assets.lottieLoadingspinner, + decoder: customDecoder, + repeat: true, + fit: BoxFit.fill, + + ) + ), + ) + ); + } + ), )), ], ), @@ -382,7 +483,8 @@ class _PlaceViewState extends State with TickerProviderStateMixin { Expanded( child: MaterialButton( onPressed: () { - poiController.isOrbit.value = !poiController.isOrbit.value; + + poiController.orbitButtonPressed(); }, color: GalaxyColors.darkBlue.withOpacity(0.5), @@ -398,7 +500,8 @@ class _PlaceViewState extends State with TickerProviderStateMixin { child: FittedBox( fit: BoxFit.contain, child: Obx((){ - lottieController = AnimationController(vsync: this,duration: const Duration(seconds: 2)); + lottieController?.dispose(); + lottieController = AnimationController(vsync: this, duration: const Duration(seconds: 2)); return (poiController.isOrbit.value?( Lottie.asset( @@ -407,6 +510,8 @@ class _PlaceViewState extends State with TickerProviderStateMixin { repeat: true, controller: lottieController, fit: BoxFit.fill, + width: 25.0, + height: 25.0, onLoaded: (c){ //lottieController.forward(from: 0.0); lottieController.repeat(); @@ -414,6 +519,7 @@ class _PlaceViewState extends State with TickerProviderStateMixin { ) ):(const ImageIcon( AssetImage(Assets.iconsOrbit), + size: 25.0, color: Colors.white, ))); }), @@ -443,7 +549,8 @@ class _PlaceViewState extends State with TickerProviderStateMixin { Expanded( child: MaterialButton( onPressed: () { - poiController.isVoicing.value = !poiController.isVoicing.value; + poiController.voiceButtonPressed(); + //poiController.isVoicing.value = !poiController.isVoicing.value; }, color: GalaxyColors.green.withOpacity(0.5), shape: RoundedRectangleBorder( @@ -458,6 +565,7 @@ class _PlaceViewState extends State with TickerProviderStateMixin { child: FittedBox( fit: BoxFit.contain, child: Obx((){ + voiceController?.dispose(); voiceController = AnimationController(vsync: this,duration: const Duration(seconds: 2)); return (poiController.isVoicing.value?( Lottie.asset( @@ -466,6 +574,8 @@ class _PlaceViewState extends State with TickerProviderStateMixin { repeat: true, controller: voiceController, fit: BoxFit.fill, + width: 25.0, + height: 25.0, onLoaded: (c){ //lottieController.forward(from: 0.0); voiceController.repeat(); @@ -474,9 +584,11 @@ class _PlaceViewState extends State with TickerProviderStateMixin { ):(const ImageIcon( AssetImage(Assets.iconsVoices), color: Colors.white, + size: 25.0, ))); }), - )), + ) + ), const SizedBox( width: 8.0, ), @@ -502,7 +614,10 @@ class _PlaceViewState extends State with TickerProviderStateMixin { ), Expanded( child: MaterialButton( - onPressed: () {}, + onPressed: () { + + Get.back(result: poiController.place.value); + }, color: GalaxyColors.yellow.withOpacity(0.5), shape: RoundedRectangleBorder( borderRadius: @@ -554,6 +669,13 @@ class _PlaceViewState extends State with TickerProviderStateMixin { ])); } + @override + void dispose() { + voiceController?.dispose(); + lottieController?.dispose(); + super.dispose(); + } + Future customDecoder(List bytes) { return LottieComposition.decodeZip(bytes, filePicker: (files) { return files.firstWhere( @@ -561,4 +683,5 @@ class _PlaceViewState extends State with TickerProviderStateMixin { ); }); } + } diff --git a/lib/screens/settings.dart b/lib/screens/settings.dart index 11d970f..cf44c8f 100644 --- a/lib/screens/settings.dart +++ b/lib/screens/settings.dart @@ -7,8 +7,8 @@ import 'package:super_liquid_galaxy_controller/generated/assets.dart'; import 'package:super_liquid_galaxy_controller/tabs/apikey_tab.dart'; import 'package:super_liquid_galaxy_controller/tabs/connection_tab.dart'; import 'package:super_liquid_galaxy_controller/tabs/sshcommands_tab.dart'; -import 'package:super_liquid_galaxy_controller/utils/api_manager.dart'; -import 'package:super_liquid_galaxy_controller/utils/lg_connection.dart'; +import 'package:super_liquid_galaxy_controller/controllers/api_manager.dart'; +import 'package:super_liquid_galaxy_controller/controllers/lg_connection.dart'; //ignore_for_file: prefer_const_constructors //ignore_for_file: prefer_const_literals diff --git a/lib/screens/test.dart b/lib/screens/test.dart index e0dd4aa..eaedb30 100644 --- a/lib/screens/test.dart +++ b/lib/screens/test.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:super_liquid_galaxy_controller/utils/speech_controller.dart'; +import 'package:super_liquid_galaxy_controller/controllers/speech_controller.dart'; class TestScreen extends StatefulWidget { const TestScreen({super.key, required this.kml}); diff --git a/lib/screens/tour_builder.dart b/lib/screens/tour_builder.dart index 82e313e..b6c69e6 100644 --- a/lib/screens/tour_builder.dart +++ b/lib/screens/tour_builder.dart @@ -10,7 +10,7 @@ import 'package:super_liquid_galaxy_controller/data_class/coordinate.dart'; import 'package:super_liquid_galaxy_controller/generated/assets.dart'; import 'package:super_liquid_galaxy_controller/screens/place_view.dart'; import 'package:super_liquid_galaxy_controller/utils/galaxy_colors.dart'; -import 'package:super_liquid_galaxy_controller/utils/tour_controller.dart'; +import 'package:super_liquid_galaxy_controller/controllers/tour_controller.dart'; import '../components/glassbox.dart'; @@ -291,9 +291,17 @@ class _TourBuilderState extends State { BorderRadius.circular( 20.0)), child: InkWell( - onTap: () { - Get.to(() => PlaceView( + onTap: () async { + var output = await Get.to(() => PlaceView( place: tourController.placeList[2*index])); + if(output != null) + { + print(output); + } + tourController.runKml(tourController.kml); + if(tourController.lookAtPosition != null) { + tourController.zoomToLocation(tourController.lookAtPosition!); + } }, borderRadius: BorderRadius.circular(20.0), @@ -392,15 +400,22 @@ class _TourBuilderState extends State { BorderRadius.circular( 20.0)), child: InkWell( - onTap: (){ + onTap: () async { if((index != ((tourController.placeList.length % 2 == 0) ? tourController.placeList.length ~/ 2 - 1 : ((tourController.placeList.length ~/ 2)))) || tourController.placeList.length % 2 == 0) { - Get.to(()=> PlaceView(place: tourController + var output = await Get.to(()=> PlaceView(place: tourController .placeList[2 * index + 1])); + if(output != null) + { + print(output); + } + tourController.runKml(tourController.kml); + if(tourController.lookAtPosition != null) { + tourController.zoomToLocation(tourController.lookAtPosition!); + } } - }, child: Padding( padding: const EdgeInsets diff --git a/lib/tabs/connection_tab.dart b/lib/tabs/connection_tab.dart index 3bb2a90..ff61061 100644 --- a/lib/tabs/connection_tab.dart +++ b/lib/tabs/connection_tab.dart @@ -5,7 +5,7 @@ import 'package:shared_preferences/shared_preferences.dart'; import 'package:super_liquid_galaxy_controller/components/galaxytextfield.dart'; import 'package:super_liquid_galaxy_controller/generated/assets.dart'; import 'package:super_liquid_galaxy_controller/utils/galaxy_colors.dart'; -import 'package:super_liquid_galaxy_controller/utils/lg_connection.dart'; +import 'package:super_liquid_galaxy_controller/controllers/lg_connection.dart'; import '../components/custom_dialog.dart'; diff --git a/lib/tabs/sshcommands_tab.dart b/lib/tabs/sshcommands_tab.dart index be373ff..2c4bd11 100644 --- a/lib/tabs/sshcommands_tab.dart +++ b/lib/tabs/sshcommands_tab.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:super_liquid_galaxy_controller/components/galaxy_button.dart'; import 'package:super_liquid_galaxy_controller/utils/galaxy_colors.dart'; -import 'package:super_liquid_galaxy_controller/utils/lg_connection.dart'; +import 'package:super_liquid_galaxy_controller/controllers/lg_connection.dart'; import 'package:get/get.dart'; //ignore_for_file: prefer_const_constructors //ignore_for_file: prefer_const_literals diff --git a/lib/utils/balloongenerator.dart b/lib/utils/balloongenerator.dart new file mode 100644 index 0000000..6dfc602 --- /dev/null +++ b/lib/utils/balloongenerator.dart @@ -0,0 +1,25 @@ +import 'constants.dart'; + +class BalloonGenerator { + static blankBalloon() => ''' + + + None + + + + #blank + 0 + + 0,0,0 + + + +'''; +} diff --git a/lib/utils/constants.dart b/lib/utils/constants.dart new file mode 100644 index 0000000..62d4966 --- /dev/null +++ b/lib/utils/constants.dart @@ -0,0 +1,84 @@ +import 'dart:math'; + +import '../generated/assets.dart'; +class Constants { + static double appBarHeight = 80; + static double tabBarWidthDivider = 5; + static double splashAspectRatio = 2864 / 3000; + static double lgZoomScale = 130000000.0; + static double appZoomScale = 11; + static double tourZoomScale = 16; + static double orbitZoomScale = 13; + static double defaultZoomScale = 2; + static double dashboardUIRoundness = 20; + static double dashboardUISpacing = 10; + static double dashboardUIHeightFactor = 0.65; + static Duration animationDuration = const Duration(milliseconds: 375); + static double animationDurationDouble = 375; + static Duration screenshotDelay = const Duration(milliseconds: 1000); + static double animationDistance = 50; + static double orbitRange = 40000; + static double tabBarTextSize = 17; + static double appBarTextSize = 18; + static double homePageTextSize = 17; + static double dashboardTextSize = 16; + static double tourTextSize = 17; + static double dashboardChartTextSize = 17; + static List tourismCategories = [ + "city_gate", + "archaeological_site", + "sights", + "attraction", + "temple", + "memorial", + "place_of_worship", + "artwork", + "viewpoint", + "monument", + "castle", + "ruines", + "tomb", + "shrine", + "wayside_cross", + "chapel", + "fort", + "tower", + "locomotive", + "battlefield", + "boundary_stone", + "default" + ]; + static List assetPaths = [ + Assets.placeIconsGate, + Assets.placeIconsArchaeology, + Assets.placeIconsSights, + Assets.placeIconsSights, + Assets.placeIconsTemple, + Assets.placeIconsObelisk, + Assets.placeIconsTemple, + Assets.placeIconsSights, + Assets.placeIconsObelisk, + Assets.placeIconsCastle, + Assets.placeIconsArchaeology, + Assets.placeIconsTombstone, + Assets.placeIconsShrine, + Assets.placeIconsTombstone, + Assets.placeIconsChapel, + Assets.placeIconsCastle, + Assets.placeIconsObelisk, + Assets.placeIconsObelisk, + Assets.placeIconsObelisk, + Assets.placeIconsStrategy, + Assets.placeIconsObelisk, + Assets.placeIconsObelisk, + ]; +} +extension ZoomLG on num { + double get zoomLG => + Constants.lgZoomScale / pow(2, this); // Formula to match zoom of GMap with LG +} + +extension RigCalculator on num { + double get rightMostRig => (this ~/ 2 +1); + double get leftMostRig => (this ~/ 2 +2); +} \ No newline at end of file diff --git a/lib/utils/geo_utils.dart b/lib/utils/geo_utils.dart index 6015ca4..1800ce4 100644 --- a/lib/utils/geo_utils.dart +++ b/lib/utils/geo_utils.dart @@ -198,13 +198,13 @@ class GeoUtils { var latFraction = (latRad(ne.latitude) - latRad(sw.latitude)) / pi; print(latFraction); - latFraction = max(0.001,latFraction); + latFraction = max(0.000001,latFraction); var lngDiff = ne.longitude - sw.longitude; var lngFraction = ((lngDiff < 0) ? (lngDiff + 360) : lngDiff) / 360; print(lngFraction); - lngFraction = max(0.001, lngFraction); + lngFraction = max(0.000001, lngFraction); var latZoom = zoom(mapDim.height, WORLD_DIM.height, latFraction); var lngZoom = zoom(mapDim.width, WORLD_DIM.width, lngFraction); diff --git a/lib/utils/kmlgenerator.dart b/lib/utils/kmlgenerator.dart index 15f9528..d9a1d1e 100644 --- a/lib/utils/kmlgenerator.dart +++ b/lib/utils/kmlgenerator.dart @@ -194,12 +194,54 @@ class KMLGenerator { a1ffaa00 + ${visList} '''; } + static String getPOIKML(PlaceInfo mainPoi, List nearbyPois) + { + String kml = ''; + kml += ''' + #main + ${mainPoi.name} + + ${mainPoi.description?.substring(0,150)} + + + ${mainPoi.coordinate.longitude},${mainPoi.coordinate.latitude} + + '''; + + for(final poi in nearbyPois) + { + if(poi.coordinate == mainPoi.coordinate) { + continue; + } + kml+=''' + #nearby + ${poi.name} + + ADDRESS: ${poi.address} \nLOCATION- Lat: ${poi.coordinate.latitude.toStringAsFixed(5)}, Long: ${poi.coordinate.longitude.toStringAsFixed(5)} + + + ${poi.coordinate.longitude},${poi.coordinate.latitude} + + '''; + } + + return kml; + } + static String generateKml(String id, String kml) { return ''' @@ -247,6 +289,24 @@ class KMLGenerator { ffffffff + + $kml @@ -833,4 +893,11 @@ class KMLGenerator { return kml; } + + static String orbitLookAtLinear(MapPosition position) => + '2smooth${position.longitude}${position.latitude}${position.zoom}${position.tilt}${position.bearing}relativeToGround'; + + static String lookAtLinearInstant(MapPosition position) => + '0.5smooth${position.longitude}${position.latitude}${position.zoom}${position.tilt}${position.bearing}relativeToGround'; + } diff --git a/lib/utils/poi_controller.dart b/lib/utils/poi_controller.dart deleted file mode 100644 index 21af236..0000000 --- a/lib/utils/poi_controller.dart +++ /dev/null @@ -1,86 +0,0 @@ -import 'package:get/get.dart'; -import 'package:super_liquid_galaxy_controller/data_class/place_info.dart'; -import 'package:super_liquid_galaxy_controller/utils/wikidatafetcher.dart'; - -import 'api_manager.dart'; -import 'lg_connection.dart'; - -class PoiController extends GetxController{ - late ApiManager apiClient; - late LGConnection connectionClient; - late WikiDataFetcher dataFetcher; - late PlaceInfo place; - - - var descriptionIsLoading = false.obs; - var descriptionIsError = false.obs; - var imageIsLoading = false.obs; - var imageIsError = false.obs; - var isOrbit = false.obs; - var isVoicing = false.obs; - - var description = ''.obs; - var imageLink = ''.obs; - @override - void onInit() { - apiClient = Get.find(); - connectionClient = Get.find(); - dataFetcher = WikiDataFetcher(); - super.onInit(); - } - - void setInfo(PlaceInfo pl) - { - place = pl; - description.value = place.description ?? ''; - imageLink.value = place.imageLink ?? ''; - } - void fetchAllInfo() async { - fetchDescription(); - loadImage(); - } - - - - - void fetchDescription() async - { - descriptionIsLoading.value = true; - descriptionIsError.value = false; - dataFetcher.setData(place); - try{ - description.value = await dataFetcher.getInfo() ?? "Loading...."; - if(description.value == "Loading....") { - throw Exception("No Data Found"); - } - place.description = description.value; - descriptionIsLoading.value = false; - descriptionIsError.value = false; - } - catch(e) - { - descriptionIsLoading.value = false; - descriptionIsError.value = true; - } - } - - void loadImage() async{ - imageIsLoading.value = true; - imageIsError.value = false; - try{ - imageLink.value = await dataFetcher.getImages() ?? ''; - place.imageLink = imageLink.value; - if(imageLink.value == "") { - throw Exception("No Data Found"); - } - imageIsLoading.value = false; - imageIsError.value = false; - } - catch(e) - { - imageIsLoading.value = false; - imageIsError.value = true; - } - print("masterLink: ${imageLink.value}"); - } -} \ No newline at end of file diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 42df6ce..0233b7b 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -6,6 +6,7 @@ import FlutterMacOS import Foundation import device_info_plus +import flutter_tts import geolocator_apple import path_provider_foundation import shared_preferences_foundation @@ -14,6 +15,7 @@ import url_launcher_macos func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) + FlutterTtsPlugin.register(with: registry.registrar(forPlugin: "FlutterTtsPlugin")) GeolocatorPlugin.register(with: registry.registrar(forPlugin: "GeolocatorPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) diff --git a/pubspec.lock b/pubspec.lock index c40f2c4..be6c604 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -235,6 +235,14 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_tts: + dependency: "direct dev" + description: + name: flutter_tts + sha256: aed2a00c48c43af043ed81145fd8503ddd793dafa7088ab137dbef81a703e53d + url: "https://pub.dev" + source: hosted + version: "4.0.2" flutter_web_plugins: dependency: transitive description: flutter diff --git a/pubspec.yaml b/pubspec.yaml index 65c6d4e..33d5eb1 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -65,6 +65,7 @@ dev_dependencies: geocoding: ^3.0.0 permission_handler: ^10.2.0 device_info_plus: ^10.1.0 + flutter_tts: ^4.0.2 # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index ce843bc..c363bd6 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -6,11 +6,14 @@ #include "generated_plugin_registrant.h" +#include #include #include #include void RegisterPlugins(flutter::PluginRegistry* registry) { + FlutterTtsPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("FlutterTtsPlugin")); GeolocatorWindowsRegisterWithRegistrar( registry->GetRegistrarForPlugin("GeolocatorWindows")); PermissionHandlerWindowsPluginRegisterWithRegistrar( diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index b3ea692..329e43f 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -3,6 +3,7 @@ # list(APPEND FLUTTER_PLUGIN_LIST + flutter_tts geolocator_windows permission_handler_windows url_launcher_windows