From cba728884ff2a8ec4de03d9a0d94de87abbeba21 Mon Sep 17 00:00:00 2001 From: Thomas Fransolet Date: Wed, 17 Apr 2024 23:34:53 +0200 Subject: [PATCH] wip map update (filter + icons (tbt)) + added section_page_detail --- lib/Screens/Agenda/event_popup.dart | 2 - lib/Screens/MainView/main_view.dart | 258 +++++++++++++++--- lib/Screens/MainView/section_page_detail.dart | 247 +++++++++++++++++ lib/Screens/Map/geo_point_filter.dart | 105 ++++--- lib/Screens/Map/google_map_view.dart | 15 +- lib/Screens/Map/map_box_view.dart | 6 +- lib/Screens/Map/map_view.dart | 104 +++---- lib/Screens/Menu/menu_view.dart | 19 +- lib/Screens/Previous/previous_view.dart | 3 +- 9 files changed, 613 insertions(+), 146 deletions(-) create mode 100644 lib/Screens/MainView/section_page_detail.dart diff --git a/lib/Screens/Agenda/event_popup.dart b/lib/Screens/Agenda/event_popup.dart index 4952903..b17f688 100644 --- a/lib/Screens/Agenda/event_popup.dart +++ b/lib/Screens/Agenda/event_popup.dart @@ -89,8 +89,6 @@ class _EventPopupState extends State { return options; } - - @override Widget build(BuildContext context) { final appContext = Provider.of(context); diff --git a/lib/Screens/MainView/main_view.dart b/lib/Screens/MainView/main_view.dart index 554aad4..ac25ee3 100644 --- a/lib/Screens/MainView/main_view.dart +++ b/lib/Screens/MainView/main_view.dart @@ -23,6 +23,7 @@ import 'package:tablet_app/Models/WeatherData.dart'; import 'package:tablet_app/Screens/Agenda/agenda_view.dart'; import 'package:tablet_app/Screens/Article/article_view.dart'; import 'package:tablet_app/Screens/Configuration/config_view.dart'; +import 'package:tablet_app/Screens/MainView/section_page_detail.dart'; import 'package:tablet_app/Screens/Weather/weather_view.dart'; import 'package:tablet_app/Screens/Map/map_context.dart'; import 'package:tablet_app/Screens/Map/map_view.dart'; @@ -38,6 +39,9 @@ import 'package:tablet_app/Services/downloadService.dart'; import 'package:tablet_app/app_context.dart'; import 'package:tablet_app/constants.dart'; import 'package:intl/intl.dart'; +import 'package:http/http.dart' as http; +import 'package:image/image.dart' as IMG; +import 'dart:ui' as ui; import '../Quizz/quizz_view.dart'; import 'language_selection.dart'; @@ -100,7 +104,7 @@ class _MainViewWidget extends State { /*if (!MQTTHelper.instance.isInstantiated) MQTTHelper.instance.connect(appContext);*/ - if(sectionSelected != null) { + /*if(sectionSelected != null) { var elementToShow; print(sectionSelected!.type); switch (sectionSelected!.type) { @@ -112,7 +116,22 @@ class _MainViewWidget extends State { longitude: null, title: '', description: '')), - child: MapViewWidget(section: sectionSelected!) /*FutureBuilder( + child: FutureBuilder( + future: getByteIcon(sectionSelected!), + builder: (context, AsyncSnapshot snapshot) { + if (snapshot.connectionState == ConnectionState.done) { + return MapViewWidget(section: sectionSelected!, markerIcon: snapshot.data); + } else if (snapshot.connectionState == ConnectionState.none) { + return Text("No data"); + } else { + return Center( + child: Container( + child: LoadingCommon() + ) + ); + } + } + ) /*FutureBuilder( future: _url, builder: (BuildContext context, AsyncSnapshot snapshot) => snapshot.hasData ? WebViewWidget(url: snapshot.data,) @@ -195,27 +214,69 @@ class _MainViewWidget extends State { mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.center, children: [ - Container( - //color: Colors.grey, - //width: size.width * 0.8, - child: Padding( - padding: const EdgeInsets.only(left: 15.0, top: 10.0, bottom: 10.0), - child: Container( - //color: Colors.grey, - child: AspectRatio( - aspectRatio: 4 / 4, - child: isImageBackground ? Container( - /*width: 125, - height: 125,*/ - decoration: boxDecoration(appContext, sectionSelected!, true), - ) : Container( - decoration: BoxDecoration( - color: sectionSelected!.imageSource == null ? kBackgroundLight : null, // default color if no image - shape: BoxShape.rectangle, - image: sectionSelected!.imageSource != null ? new DecorationImage( - fit: BoxFit.cover, - image: ImageCustomProvider.getImageProvider(appContext, sectionSelected!.imageId!, sectionSelected!.imageSource!), - ): null, + InkWell( + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) { + return Scaffold( + body: ChangeNotifierProvider( + create: (_) => + MapContext(new MapMarker( + latitude: null, + longitude: null, + title: '', + description: '')), + child: FutureBuilder( + future: getByteIcon(sectionSelected!), + builder: (context, AsyncSnapshot snapshot) { + if (snapshot.connectionState == ConnectionState.done) { + return MapViewWidget(section: sectionSelected!, markerIcon: snapshot.data); + } else if (snapshot.connectionState == ConnectionState.none) { + return Text("No data"); + } else { + return Center( + child: Container( + child: LoadingCommon() + ) + ); + } + } + ) /*FutureBuilder( + future: _url, + builder: (BuildContext context, AsyncSnapshot snapshot) => snapshot.hasData + ? WebViewWidget(url: snapshot.data,) + : CircularProgressIndicator()),*/ + ) + + ); + }, + ),// For pushAndRemoveUntil + ); + }, + child: Container( + color: Colors.grey, + //width: size.width * 0.8, + child: Padding( + padding: const EdgeInsets.only(left: 15.0, top: 10.0, bottom: 10.0), + child: Container( + //color: Colors.grey, + child: AspectRatio( + aspectRatio: 4 / 4, + child: isImageBackground ? Container( + /*width: 125, + height: 125,*/ + decoration: boxDecoration(appContext, sectionSelected!, true), + ) : Container( + decoration: BoxDecoration( + color: sectionSelected!.imageSource == null ? kBackgroundLight : null, // default color if no image + shape: BoxShape.rectangle, + image: sectionSelected!.imageSource != null ? new DecorationImage( + fit: BoxFit.cover, + image: ImageCustomProvider.getImageProvider(appContext, sectionSelected!.imageId!, sectionSelected!.imageSource!), + ): null, + ), ), ), ), @@ -327,7 +388,7 @@ class _MainViewWidget extends State { ), ),*/ ); - } else { + } else {*/ return Scaffold( resizeToAvoidBottomInset: false, body: Container( @@ -384,7 +445,7 @@ class _MainViewWidget extends State { return Text(""); } else { - return getGridSections(appContext); + return getGridSections(appContext, textColor); } } else if (snapshot.connectionState == ConnectionState.none) { return Text("No data"); @@ -396,7 +457,7 @@ class _MainViewWidget extends State { ); } } - ) : getGridSections(appContext), + ) : getGridSections(appContext, textColor), ), ), /*if(configurationDTO.weatherCity != null && configurationDTO.weatherCity!.length > 2 && configurationDTO.weatherResult != null) @@ -417,7 +478,7 @@ class _MainViewWidget extends State { ]), ), ); - } + //} } Future getCurrentConfiguration(dynamic appContext) async { @@ -509,7 +570,7 @@ class _MainViewWidget extends State { return sectionsLocal; } - getGridSections(AppContext appContext) { + getGridSections(AppContext appContext, Color textColor) { TabletAppContext tabletAppContext = appContext.getContext() as TabletAppContext; if(sectionsLocal != null) { @@ -526,7 +587,16 @@ class _MainViewWidget extends State { return InkWell( onTap: () { setState(() { - sectionSelected = sectionsLocal![index]; + //sectionSelected = sectionsLocal![index]; + + Navigator.push( + context, + MaterialPageRoute( + builder: (context) { + return SectionPageDetail(configurationDTO: configurationDTO, sectionDTO: sectionsLocal![index], textColor: textColor, isImageBackground: isImageBackground, elementToShow: getContent(sectionsLocal![index], isImageBackground)); + }, + ),// For pushAndRemoveUntil + ); }); }, child: Container( @@ -599,21 +669,6 @@ class _MainViewWidget extends State { } } -double calculateFontSize(double parentWidth, double parentHeight, double baseSize) { - // La taille de base est basée sur la taille définie dans vos constantes (kWebMenuTitleDetailSize ou kMenuTitleDetailSize). - // Vous pouvez ajuster ce facteur en fonction de vos besoins. - double scaleFactor = 0.8; - - // Calculez la taille de la police en fonction de la largeur et de la hauteur maximales disponibles - //double calculatedFontSize = parentWidth * scaleFactor; - - // Vous pouvez également prendre en compte la hauteur ici si nécessaire - double calculatedFontSize = min(parentWidth, parentHeight) * scaleFactor; - - // Utilisez la plus petite valeur entre la taille de base et la taille calculée - return calculatedFontSize < baseSize ? calculatedFontSize : baseSize; -} - boxDecoration(AppContext appContext, SectionDTO section, bool isSelected) { TabletAppContext tabletAppContext = appContext.getContext() as TabletAppContext; return BoxDecoration( @@ -634,4 +689,119 @@ boxDecoration(AppContext appContext, SectionDTO section, bool isSelected) { ), ], ); +} + +Future>> getByteIcons(SectionDTO section) async { + var mapDTO = MapDTO.fromJson(jsonDecode(section.data!)); + var selectedMarkerIcon; + + if (mapDTO != null && mapDTO.iconSource != null) { + if (kIsWeb) { + Uint8List fileData = await http.readBytes(Uri.parse(mapDTO.iconSource!)); + selectedMarkerIcon = resizeImage(fileData, 40); + } else { + final ByteData imageData = await NetworkAssetBundle(Uri.parse(mapDTO.iconSource!)).load(""); + selectedMarkerIcon = await getBytesFromAsset(imageData, 50); + } + } else { + // Icône par défaut + final ByteData bytes = await rootBundle.load('assets/icons/marker.png'); + selectedMarkerIcon = await getBytesFromAsset(bytes, 25); + } + + List> icons = []; + + icons.add({'id': null, 'icon': selectedMarkerIcon}); + + mapDTO!.categories!.forEach((cat) async { + if (cat.iconUrl != null) { + Uint8List categoryIcon; + if (kIsWeb) { + categoryIcon = await http.readBytes(Uri.parse(cat.iconUrl!)); + } else { + final ByteData imageData = await NetworkAssetBundle(Uri.parse(cat.iconUrl!)).load(""); + categoryIcon = await getBytesFromAsset(imageData, 50); + } + icons.add({'id': cat.id, 'icon': categoryIcon}); + } + }); + + return icons; +} + +Future getBytesFromAsset(ByteData data, int width) async { + //ByteData data = await rootBundle.load(path); + ui.Codec codec = await ui.instantiateImageCodec(data.buffer.asUint8List(), + targetWidth: width); + ui.FrameInfo fi = await codec.getNextFrame(); + return (await fi.image.toByteData(format: ui.ImageByteFormat.png)) + !.buffer + .asUint8List(); +} + +Uint8List resizeImage(Uint8List data, int width) { + Uint8List resizedData = data; + IMG.Image img = IMG.decodeImage(data)!; + IMG.Image resized = IMG.copyResize(img, width: width); + resizedData = Uint8List.fromList(IMG.encodeJpg(resized)); + return resizedData; +} + +Widget getContent(SectionDTO sectionSelected, bool isImageBackground) { + switch (sectionSelected.type) { + case SectionType.Map : // MAP + return ChangeNotifierProvider( + create: (_) => + MapContext(new MapMarker( + latitude: null, + longitude: null, + title: '', + description: '')), + child: FutureBuilder( + future: getByteIcons(sectionSelected), + builder: (context, AsyncSnapshot snapshot) { + if (snapshot.connectionState == ConnectionState.done) { + return MapViewWidget(section: sectionSelected, icons: snapshot.data); + } else if (snapshot.connectionState == ConnectionState.none) { + return Text("No data"); + } else { + return Center( + child: Container( + child: LoadingCommon() + ) + ); + } + } + ) /*FutureBuilder( + future: _url, + builder: (BuildContext context, AsyncSnapshot snapshot) => snapshot.hasData + ? WebViewWidget(url: snapshot.data,) + : CircularProgressIndicator()),*/ + ); + case SectionType.Web : // WEB + return WebView(section: sectionSelected); + case SectionType.Video : // Video + return VideoView(section: sectionSelected); + case SectionType.Slider : + return SliderView(section: sectionSelected); + case SectionType.Menu : + return MenuView(section: sectionSelected!, isImageBackground: isImageBackground); + case SectionType.Quizz : + return QuizzView(section: sectionSelected); + case SectionType.Pdf : + return PDFViewWidget(section: sectionSelected); + case SectionType.Puzzle : + return PuzzleView(section: sectionSelected); + case SectionType.Agenda : + return AgendaView(section: sectionSelected); + /*case SectionType.article : // TODO + elementToShow = ArticleView(section: sectionSelected); + break;*/ + case SectionType.Weather : + return WeatherView(section: sectionSelected); + default: + return Text("Ce type n'est pas supporté"); + }; + + } \ No newline at end of file diff --git a/lib/Screens/MainView/section_page_detail.dart b/lib/Screens/MainView/section_page_detail.dart new file mode 100644 index 0000000..253e093 --- /dev/null +++ b/lib/Screens/MainView/section_page_detail.dart @@ -0,0 +1,247 @@ +import 'dart:async'; +import 'dart:typed_data'; +import 'package:enum_to_string/enum_to_string.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_widget_from_html/flutter_widget_from_html.dart'; +import 'package:google_maps_flutter/google_maps_flutter.dart'; +import 'package:manager_api/api.dart'; +import 'package:provider/provider.dart'; +import 'package:tablet_app/Components/loading_common.dart'; +import 'package:tablet_app/Components/multi_select_container.dart'; +import 'package:tablet_app/Helpers/ImageCustomProvider.dart'; +import 'package:tablet_app/Helpers/translationHelper.dart'; +import 'package:tablet_app/Models/map-marker.dart'; +import 'package:tablet_app/Models/tabletContext.dart'; +import 'package:tablet_app/Screens/Map/geo_point_filter.dart'; +import 'package:tablet_app/Screens/Map/map_context.dart'; +import 'package:html/parser.dart' show parse; +import 'package:tablet_app/app_context.dart'; +import 'package:tablet_app/constants.dart'; + +class SectionPageDetail extends StatefulWidget { + final ConfigurationDTO configurationDTO; + final SectionDTO sectionDTO; + final Uint8List? selectedMarkerIcon; + final Color textColor; + final bool isImageBackground; + final Widget elementToShow; + const SectionPageDetail({ + Key? key, + required this.configurationDTO, + required this.sectionDTO, + this.selectedMarkerIcon, + required this.textColor, + required this.isImageBackground, + required this.elementToShow, + }) : super(key: key); + + @override + _SectionPageDetailState createState() => _SectionPageDetailState(); +} + +class _SectionPageDetailState extends State { + bool init = false; + + @override + Widget build(BuildContext context) { + final appContext = Provider.of(context); + TabletAppContext tabletAppContext = appContext.getContext() as TabletAppContext; + Size size = MediaQuery.of(context).size; + + return Scaffold( + resizeToAvoidBottomInset: false, + body: SingleChildScrollView( + child: Container( + height: size.height, + width: size.width, + color: widget.configurationDTO.imageId == null ? widget.configurationDTO.secondaryColor != null ? new Color(int.parse(widget.configurationDTO.secondaryColor!.split('(0x')[1].split(')')[0], radix: 16)): kBackgroundGrey : null, + decoration: widget.configurationDTO.imageId != null ? BoxDecoration( + image: new DecorationImage( + fit: BoxFit.cover, + colorFilter: new ColorFilter.mode(Colors.white.withOpacity(0.8), BlendMode.lighten), + image: ImageCustomProvider.getImageProvider(appContext, widget.configurationDTO.imageId!, widget.configurationDTO.imageSource!), + ), + ) : null, + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Container( + decoration : BoxDecoration( + color: kBackgroundLight, + shape: BoxShape.rectangle, + borderRadius: BorderRadius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 30.0), + boxShadow: [ + BoxShadow( + color: kBackgroundSecondGrey, + spreadRadius: 0.5, + blurRadius: 5, + offset: Offset(0, 1.5), // changes position of shadow + ), + ], + ), + child: Column( + children: [ + Expanded( + flex: 1, + //height: size.height * 0.1, + child: Container( + //color: Colors.greenAccent, + width: size.width, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + //color: Colors.grey, + //width: size.width * 0.8, + child: Padding( + padding: const EdgeInsets.only(left: 15.0, top: 10.0, bottom: 10.0), + child: Container( + //color: Colors.grey, + child: AspectRatio( + aspectRatio: 4 / 4, + child: widget.isImageBackground ? Container( + /*width: 125, + height: 125,*/ + decoration: boxDecoration(appContext, widget.sectionDTO, true), + ) : Container( + decoration: BoxDecoration( + color: widget.sectionDTO.imageSource == null ? kBackgroundLight : null, // default color if no image + shape: BoxShape.rectangle, + image: widget.sectionDTO.imageSource != null ? new DecorationImage( + fit: BoxFit.cover, + image: ImageCustomProvider.getImageProvider(appContext, widget.sectionDTO.imageId!, widget.sectionDTO.imageSource!), + ): null, + ), + ), + ), + ), + ), + ), + Container( + //width: size.width, + //color: Colors.green, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Align( + alignment: Alignment.center, + child: HtmlWidget( + widget.sectionDTO.title!.firstWhere((translation) => translation.language == appContext.getContext().language).value!, + textStyle: new TextStyle(fontSize: kIsWeb ? kWebSectionTitleDetailSize : kSectionTitleDetailSize, color: widget.textColor, fontFamily: 'Roboto'), + ) + ), + if(widget.sectionDTO.description!.firstWhere((translation) => translation.language == appContext.getContext().language).value != null && widget.sectionDTO.description!.firstWhere((translation) => translation.language == appContext.getContext().language).value!.trim().isNotEmpty) + Align( + //alignment: Alignment.center, + child: HtmlWidget( + widget.sectionDTO.description!.firstWhere((translation) => translation.language == appContext.getContext().language).value!, + textStyle: new TextStyle(fontSize: kIsWeb? kWebSectionDescriptionDetailSize : kSectionDescriptionDetailSize, color: widget.textColor, fontFamily: 'Roboto'), + ) + ) + ], + ), + ), + Padding( + padding: const EdgeInsets.only(right: 15.0), + child: Container( + height: size.height *0.08, + width: size.width *0.08, + child: FittedBox( + child: FloatingActionButton.extended( + backgroundColor: kBackgroundColor, + focusColor: kBackgroundColor, + splashColor: kBackgroundColor, + onPressed: () { + Navigator.pop(context); + }, + icon: Icon(Icons.arrow_back, color: Colors.grey), + label: Text(TranslationHelper.getFromLocale("menu", appContext.getContext()), style: TextStyle(color: Colors.black)) + ), + ), + ), + ) + ], + ), + ), + ), + Expanded( + flex: 9, + child: Padding( + padding: widget.sectionDTO.type != SectionType.Slider ? const EdgeInsets.only(left: 15.0, right: 15.0, top: 10.0) : const EdgeInsets.only(top: 10.0), + child: Container( + width: size.width, + //height: size.height * 0.9, + /*decoration: sectionSelected!.type != SectionType.Video && sectionSelected!.type != SectionType.Web && sectionSelected!.type != SectionType.Slider && sectionSelected!.type != SectionType.Map ? BoxDecoration( + //color: kBackgroundLight, + shape: BoxShape.rectangle, + borderRadius: BorderRadius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 30.0), + /*boxShadow: [ + BoxShadow( + color: kBackgroundSecondGrey, + spreadRadius: 0.5, + blurRadius: 5, + offset: Offset(0, 1.5), // changes position of shadow + ), + ],*/ + ) :null,*/ + child: Padding( + padding: const EdgeInsets.only(bottom: 8.0), + child: widget.elementToShow), + ), + ), + ) + ], + ), + ), + ), + ), + ), + /*floatingActionButtonLocation: FloatingActionButtonLocation.endTop, + floatingActionButton: Padding( + padding: const EdgeInsets.only(top: 10.0), + child: Container( + height: size.height *0.08, + width: size.width *0.08, + child: FittedBox( + child: FloatingActionButton.extended( + backgroundColor: kBackgroundColor, + focusColor: kBackgroundColor, + splashColor: kBackgroundColor, + onPressed: () { + setState(() { + sectionSelected = null; + }); + }, + icon: Icon(Icons.arrow_back, color: Colors.grey), + label: Text("Menu", style: TextStyle(color: Colors.black)) + ), + ), + ), + ),*/ + ); + } +} + +boxDecoration(AppContext appContext, SectionDTO section, bool isSelected) { + TabletAppContext tabletAppContext = appContext.getContext() as TabletAppContext; + return BoxDecoration( + color: !isSelected ? kBackgroundLight : section.imageSource == null ? kBackgroundLight : null, + shape: BoxShape.rectangle, + borderRadius: BorderRadius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 30.0), + image: section.imageSource != null ? new DecorationImage( + fit: BoxFit.cover, + colorFilter: !isSelected? new ColorFilter.mode(kBackgroundLight.withOpacity(0.2), BlendMode.dstATop) : null, + image: ImageCustomProvider.getImageProvider(appContext, section.imageId!, section.imageSource!), + ): null, + boxShadow: [ + BoxShadow( + color: kBackgroundSecondGrey, + spreadRadius: 0.5, + blurRadius: 5, + offset: Offset(0, 1.5), // changes position of shadow + ), + ], + ); +} \ No newline at end of file diff --git a/lib/Screens/Map/geo_point_filter.dart b/lib/Screens/Map/geo_point_filter.dart index 0d5b483..f7812ea 100644 --- a/lib/Screens/Map/geo_point_filter.dart +++ b/lib/Screens/Map/geo_point_filter.dart @@ -19,8 +19,9 @@ class GeoPointFilter extends StatefulWidget { final List geoPoints; final List categories; final Function(List?) filteredPoints; + final MapProvider provider; - GeoPointFilter({required this.language, required this.geoPoints, required this.categories, required this.filteredPoints}); + GeoPointFilter({required this.language, required this.geoPoints, required this.categories, required this.filteredPoints, required this.provider}); @override _GeoPointFilterState createState() => _GeoPointFilterState(); @@ -33,6 +34,7 @@ class _GeoPointFilterState extends State { late ValueNotifier _searchTextNotifier; final TextEditingController _searchController = TextEditingController(); FocusNode focusNode = new FocusNode(); + bool _isExpanded = true; @override void initState() { @@ -51,6 +53,12 @@ class _GeoPointFilterState extends State { super.dispose(); } + void _toggleExpansion() { + setState(() { + _isExpanded = !_isExpanded; + }); + } + void _onSearchTextChanged() { //filterNodes(_searchTextNotifier.value); } @@ -100,10 +108,10 @@ class _GeoPointFilterState extends State { : _filterNodesBySearchText(searchText); // if unfocus, then - if(searchText.isEmpty && !focusNode.hasFocus) { + //if(searchText.isEmpty) { // widget.filteredPoints = //todo sendFilteredGeoPoint(); - } + //} }); } @@ -157,7 +165,7 @@ class _GeoPointFilterState extends State { return Positioned( left: 5, - top: 35, + top: widget.provider == MapProvider.Google ? 10 : 35, child: Container( width: size.width * 0.3, decoration: BoxDecoration( @@ -168,47 +176,70 @@ class _GeoPointFilterState extends State { padding: const EdgeInsets.all(8.0), child: Column( children: [ - Padding( - padding: const EdgeInsets.only(bottom: 8.0, top: 4.0), - child: TextField( - focusNode: focusNode, - controller: _searchController, - onChanged: (value) { - filterNodes(); - }, - cursorColor: Colors.black, - style: TextStyle(color: Colors.black), - decoration: InputDecoration( - labelText: TranslationHelper.getFromLocale("map.search", appContext.getContext()), - labelStyle: TextStyle( - color: focusNode.hasFocus ? primaryColor : Colors.black - ), - focusColor: primaryColor, - focusedBorder: OutlineInputBorder( - borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 20.0)), - borderSide: BorderSide(color: primaryColor)), - //labelStyle: TextStyle(color: primaryColor), - suffixIcon: IconButton( - icon: _searchController.text.isNotEmpty ? Icon(Icons.close) : Icon(Icons.search), - onPressed: () { - if(_searchController.text.isNotEmpty) { - _searchController.text = ""; - } - filterNodes(); - if(_searchController.text.isNotEmpty) { - focusNode.unfocus(); - } - }, + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + SizedBox( + height: 60, + width: (size.width * 0.20), + child: Padding( + padding: const EdgeInsets.only(left: 10.0, bottom: 8.0, top: 4.0), + child: TextField( + focusNode: focusNode, + controller: _searchController, + onChanged: (value) { + filterNodes(); + }, + cursorColor: Colors.black, + style: TextStyle(color: Colors.black), + decoration: InputDecoration( + labelText: TranslationHelper.getFromLocale("map.search", appContext.getContext()), + labelStyle: TextStyle( + color: focusNode.hasFocus ? primaryColor : Colors.black + ), + focusColor: primaryColor, + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 20.0)), + borderSide: BorderSide(color: primaryColor)), + //labelStyle: TextStyle(color: primaryColor), + suffixIcon: IconButton( + icon: _searchController.text.isNotEmpty ? Icon(Icons.close) : Icon(Icons.search), + onPressed: () { + if(_searchController.text.isNotEmpty) { + _searchController.text = ""; + } + filterNodes(); + if(_searchController.text.isNotEmpty) { + focusNode.unfocus(); + } + }, + ), + ), + ), ), ), - ), + SizedBox( + width: 50, + height: 60, + child: Align( + alignment: Alignment.centerRight, + child: InkWell( + onTap: _toggleExpansion, + child: Padding( + padding: const EdgeInsets.only(top: 4.0, right: 3.0), + child: Icon(_isExpanded ? Icons.expand_more : Icons.chevron_right, color: primaryColor), + ), + ), + ), + ), + ], ), ValueListenableBuilder( valueListenable: _searchTextNotifier, builder: (context, value, _) { return Container( //color: Colors.greenAccent, - height: size.height * 0.65, + height: _isExpanded ? widget.provider == MapProvider.Google ? size.height * 0.68 : size.height * 0.65 : 0, width: size.width * 0.3, child: GenerateTree( data: _filteredNodes, diff --git a/lib/Screens/Map/google_map_view.dart b/lib/Screens/Map/google_map_view.dart index f88a067..1867544 100644 --- a/lib/Screens/Map/google_map_view.dart +++ b/lib/Screens/Map/google_map_view.dart @@ -16,13 +16,13 @@ import 'package:tablet_app/app_context.dart'; import 'package:tablet_app/constants.dart'; class GoogleMapView extends StatefulWidget { - final MapDTO? mapDTO; - final Uint8List? selectedMarkerIcon; + final MapDTO mapDTO; + final List> icons; final String? language; const GoogleMapView({ Key? key, - this.mapDTO, - this.selectedMarkerIcon, + required this.mapDTO, + required this.icons, this.language, }) : super(key: key); @@ -59,7 +59,8 @@ class _GoogleMapViewState extends State { double.tryParse(mapMarker.latitude!)!, double.tryParse(mapMarker.longitude!)!, ), - icon: widget.selectedMarkerIcon != null ? BitmapDescriptor.fromBytes(widget.selectedMarkerIcon!) : BitmapDescriptor.defaultMarker, + icon: point.categorie == null ? BitmapDescriptor.fromBytes(widget.icons.where((i) => i['id'] == null).first['icon']) : widget.icons.any((i) => i['id'] == point.categorieId) ? BitmapDescriptor.fromBytes(widget.icons.where((i) => i['id'] == point.categorieId).first['icon']) : BitmapDescriptor.fromBytes(widget.icons.where((i) => i['id'] == null).first['icon']), //widget.selectedMarkerIcon, + //widget.selectedMarkerIcon != null ? BitmapDescriptor.fromBytes(widget.selectedMarkerIcon!) : BitmapDescriptor.defaultMarker, /*icon: BitmapDescriptor.defaultMarkerWithHue( BitmapDescriptor.hueYellow, ),*/ @@ -173,7 +174,7 @@ class _GoogleMapViewState extends State { }, ), ), - Positioned( + /*Positioned( left: 5, top: 35, child: SizedBox( @@ -214,7 +215,7 @@ class _GoogleMapViewState extends State { }, ), ), - ), + ),*/ ], ); } diff --git a/lib/Screens/Map/map_box_view.dart b/lib/Screens/Map/map_box_view.dart index 3531828..cb73912 100644 --- a/lib/Screens/Map/map_box_view.dart +++ b/lib/Screens/Map/map_box_view.dart @@ -20,13 +20,13 @@ import 'package:tablet_app/constants.dart'; class MapBoxView extends StatefulWidget { final MapDTO? mapDTO; final List geoPoints; - final Uint8List? selectedMarkerIcon; + final List> icons; final String? language; const MapBoxView({ Key? key, this.mapDTO, required this.geoPoints, - this.selectedMarkerIcon, + required this.icons, this.language, }) : super(key: key); @@ -87,7 +87,7 @@ class _MapBoxViewState extends State { symbolSortKey: 10, iconColor: 0, iconImage: null, - image: widget.selectedMarkerIcon, //widget.selectedMarkerIcon, + image: point.categorie == null ? widget.icons.where((i) => i['id'] == null).first['icon'] : widget.icons.any((i) => i['id'] == point.categorieId) ? widget.icons.where((i) => i['id'] == point.categorieId).first['icon'] : widget.icons.where((i) => i['id'] == null).first['icon'], //widget.selectedMarkerIcon, )); // , i++; diff --git a/lib/Screens/Map/map_view.dart b/lib/Screens/Map/map_view.dart index 8702e48..5fa793e 100644 --- a/lib/Screens/Map/map_view.dart +++ b/lib/Screens/Map/map_view.dart @@ -1,33 +1,34 @@ -import 'dart:async'; +//import 'dart:async'; import 'dart:convert'; -import 'dart:typed_data'; +// 'dart:typed_data'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:google_maps_flutter/google_maps_flutter.dart'; +// 'package:flutter/services.dart'; +//import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'package:manager_api/api.dart'; import 'package:provider/provider.dart'; -import 'package:tablet_app/Components/loading.dart'; -import 'package:tablet_app/Components/loading_common.dart'; +/*import 'package:tablet_app/Components/loading.dart'; +import 'package:tablet_app/Components/loading_common.dart';*/ import 'package:tablet_app/Models/map-marker.dart'; -import 'dart:ui' as ui; +//import 'dart:ui' as ui; import 'package:flutter/widgets.dart'; import 'package:tablet_app/Models/tabletContext.dart'; import 'package:tablet_app/Screens/Map/geo_point_filter.dart'; import 'package:tablet_app/Screens/Map/map_box_view.dart'; import 'package:tablet_app/Screens/Map/marker_view.dart'; -import 'package:http/http.dart' as http; +//import 'package:http/http.dart' as http; import '../../app_context.dart'; import 'google_map_view.dart'; -import 'package:image/image.dart' as IMG; +//import 'package:image/image.dart' as IMG; //Set markers = {}; List markersList = []; class MapViewWidget extends StatefulWidget { - final SectionDTO? section; - MapViewWidget({Key? key, this.section}) : super(key: key); + final SectionDTO section; + final List> icons; + MapViewWidget({Key? key, required this.section, required this.icons}) : super(key: key); @override _MapViewWidget createState() => _MapViewWidget(); @@ -36,10 +37,10 @@ class MapViewWidget extends StatefulWidget { class _MapViewWidget extends State { MapDTO? mapDTO; //Completer _controller = Completer(); - Uint8List? selectedMarkerIcon; + //Uint8List? selectedMarkerIcon; late ValueNotifier> _geoPoints = ValueNotifier>([]); - Future getBytesFromAsset(ByteData data, int width) async { + /*Future getBytesFromAsset(ByteData data, int width) async { //ByteData data = await rootBundle.load(path); ui.Codec codec = await ui.instantiateImageCodec(data.buffer.asUint8List(), targetWidth: width); @@ -47,11 +48,11 @@ class _MapViewWidget extends State { return (await fi.image.toByteData(format: ui.ImageByteFormat.png)) !.buffer .asUint8List(); - } + }*/ @override void initState() { - mapDTO = MapDTO.fromJson(jsonDecode(widget.section!.data!)); + mapDTO = MapDTO.fromJson(jsonDecode(widget.section.data!)); _geoPoints.value = mapDTO!.points!; super.initState(); } @@ -73,41 +74,10 @@ class _MapViewWidget extends State { //final mapContext = Provider.of(context); final appContext = Provider.of(context); TabletAppContext tabletAppContext = appContext.getContext() as TabletAppContext; - return FutureBuilder( + /*return FutureBuilder( future: getByteIcon(mapDTO!.iconSource), builder: (context, AsyncSnapshot snapshot) { if (snapshot.connectionState == ConnectionState.done) { - return Stack( - children: [ - ValueListenableBuilder>( - valueListenable: _geoPoints, - builder: (context, value, _) { - switch(mapDTO!.mapProvider) { - case MapProvider.Google: - return GoogleMapView(language: appContext.getContext().language, mapDTO: mapDTO, selectedMarkerIcon: selectedMarkerIcon); - case MapProvider.MapBox: - return MapBoxView(language: appContext.getContext().language, geoPoints: value, mapDTO: mapDTO, selectedMarkerIcon: selectedMarkerIcon); - default: - // By default google - return GoogleMapView(language: appContext.getContext().language, mapDTO: mapDTO, selectedMarkerIcon: selectedMarkerIcon); - } - } - ), - GeoPointFilter( - language: tabletAppContext.language!, - geoPoints: mapDTO!.points!, - categories: mapDTO!.categories!, - filteredPoints: (value) { - _geoPoints.value = value!; - }), - MarkerViewWidget(), - ] - /*floatingActionButton: FloatingActionButton.extended( - onPressed: _goToTheLake, - label: Text('To the lake!'), - icon: Icon(Icons.directions_boat), - ),*/ - ); } else if (snapshot.connectionState == ConnectionState.none) { return Text("No data"); } else { @@ -118,10 +88,42 @@ class _MapViewWidget extends State { ); } } + );*/ + return Stack( + children: [ + ValueListenableBuilder>( + valueListenable: _geoPoints, + builder: (context, value, _) { + switch(mapDTO!.mapProvider) { + case MapProvider.Google: + return GoogleMapView(language: appContext.getContext().language, mapDTO: mapDTO!, icons: widget.icons); + case MapProvider.MapBox: + return MapBoxView(language: appContext.getContext().language, geoPoints: value, mapDTO: mapDTO, icons: widget.icons); + default: + // By default google + return GoogleMapView(language: appContext.getContext().language, mapDTO: mapDTO!, icons: widget.icons); + } + } + ), + GeoPointFilter( + language: tabletAppContext.language!, + geoPoints: mapDTO!.points!, + categories: mapDTO!.categories!, + provider: mapDTO!.mapProvider!, + filteredPoints: (value) { + _geoPoints.value = value!; + }), + MarkerViewWidget(), + ] + /*floatingActionButton: FloatingActionButton.extended( + onPressed: _goToTheLake, + label: Text('To the lake!'), + icon: Icon(Icons.directions_boat), + ),*/ ); } - getByteIcon(String? source) async { + /*getByteIcon(String? source) async { if(source != null) { if(kIsWeb) { Uint8List fileData = await http.readBytes(Uri.parse(source)); @@ -135,15 +137,15 @@ class _MapViewWidget extends State { final ByteData bytes = await rootBundle.load('assets/icons/marker.png'); selectedMarkerIcon = await getBytesFromAsset(bytes, 25); } - } + }*/ - Uint8List resizeImage(Uint8List data, int width) { + /*Uint8List resizeImage(Uint8List data, int width) { Uint8List resizedData = data; IMG.Image img = IMG.decodeImage(data)!; IMG.Image resized = IMG.copyResize(img, width: width); resizedData = Uint8List.fromList(IMG.encodeJpg(resized)); return resizedData; - } + }*/ /*Future _goToTheLake() async { final GoogleMapController controller = await _controller.future; diff --git a/lib/Screens/Menu/menu_view.dart b/lib/Screens/Menu/menu_view.dart index cac8298..3b41893 100644 --- a/lib/Screens/Menu/menu_view.dart +++ b/lib/Screens/Menu/menu_view.dart @@ -6,10 +6,12 @@ import 'package:flutter/material.dart'; import 'package:flutter_widget_from_html/flutter_widget_from_html.dart'; import 'package:manager_api/api.dart'; import 'package:provider/provider.dart'; +import 'package:tablet_app/Components/loading_common.dart'; import 'package:tablet_app/Helpers/ImageCustomProvider.dart'; import 'package:tablet_app/Models/map-marker.dart'; import 'package:tablet_app/Models/tabletContext.dart'; import 'package:tablet_app/Screens/Agenda/agenda_view.dart'; +import 'package:tablet_app/Screens/MainView/main_view.dart'; import 'package:tablet_app/Screens/Map/map_context.dart'; import 'package:tablet_app/Screens/Map/map_view.dart'; import 'package:tablet_app/Screens/PDF/pdf_view.dart'; @@ -68,7 +70,22 @@ class _MenuView extends State { longitude: null, title: '', description: '')), - child: MapViewWidget(section: selectedSection) /*FutureBuilder( + child: FutureBuilder( + future: getByteIcons(selectedSection!), + builder: (context, AsyncSnapshot snapshot) { + if (snapshot.connectionState == ConnectionState.done) { + return MapViewWidget(section: selectedSection!, icons: snapshot.data); + } else if (snapshot.connectionState == ConnectionState.none) { + return Text("No data"); + } else { + return Center( + child: Container( + child: LoadingCommon() + ) + ); + } + } + ) /*FutureBuilder( future: _url, builder: (BuildContext context, AsyncSnapshot snapshot) => snapshot.hasData ? WebViewWidget(url: snapshot.data,) diff --git a/lib/Screens/Previous/previous_view.dart b/lib/Screens/Previous/previous_view.dart index 6df18f0..210597e 100644 --- a/lib/Screens/Previous/previous_view.dart +++ b/lib/Screens/Previous/previous_view.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:manager_api/api.dart'; import 'package:provider/provider.dart'; import 'package:tablet_app/Models/map-marker.dart'; import 'package:tablet_app/Screens/Map/map_context.dart'; @@ -269,7 +270,7 @@ class _PreviousViewWidget extends State with TickerProviderS longitude: null, title: '', description: '')), - child: MapViewWidget() /*FutureBuilder( + child: MapViewWidget(section: SectionDTO(), icons: []) /*FutureBuilder( future: _url, builder: (BuildContext context, AsyncSnapshot snapshot) => snapshot.hasData ? WebViewWidget(url: snapshot.data,)