From ef89b623d253985797d37a68891c533872a7d281 Mon Sep 17 00:00:00 2001 From: Thomas Fransolet Date: Fri, 19 Apr 2024 15:20:06 +0200 Subject: [PATCH] update map view + adapt menu view --- lib/Helpers/translations.dart | 30 +- lib/Screens/MainView/main_view.dart | 529 +++++------------- lib/Screens/MainView/section_page_detail.dart | 17 +- lib/Screens/Map/geo_point_filter.dart | 72 ++- lib/Screens/Map/google_map_view.dart | 62 +- lib/Screens/Map/map_box_view.dart | 25 +- lib/Screens/Map/map_context.dart | 12 +- lib/Screens/Map/map_view.dart | 8 +- lib/Screens/Map/marker_view.dart | 358 ++++++++++-- lib/Screens/Menu/menu_view.dart | 290 +++------- lib/Screens/Previous/previous_view.dart | 6 +- lib/api/swagger.yaml | 12 + manager_api/doc/CategorieDTO.md | 1 + manager_api/doc/GeoPointDTO.md | 2 + manager_api/doc/MapDTO.md | 2 + manager_api/lib/model/geo_point_dto.dart | 24 +- manager_api/lib/model/map_dto.dart | 58 +- manager_api/lib/model/section_type.dart | 2 +- 18 files changed, 753 insertions(+), 757 deletions(-) diff --git a/lib/Helpers/translations.dart b/lib/Helpers/translations.dart index 17544e3..c4a5952 100644 --- a/lib/Helpers/translations.dart +++ b/lib/Helpers/translations.dart @@ -15,7 +15,8 @@ List translations = [ "menu": "Menu", "quiz.seeResponses": "Voir les réponses", "quiz.restart": "Recommencer", - "map.search": "Rechercher" + "map.search": "Rechercher", + "back": "Retour" }), Translation(language: "EN", data: { "weather.hourly": "Hourly", @@ -31,7 +32,8 @@ List translations = [ "menu": "Menu", "quiz.seeResponses": "See the answers", "quiz.restart": "Restart", - "map.search": "Search" + "map.search": "Search", + "back": "Back" }), Translation(language: "DE", data: { "weather.hourly": "Nächste Stunden", @@ -47,7 +49,8 @@ List translations = [ "menu": "Speisekarte", "quiz.seeResponses": "Sehen Sie sich die Antworten an", "quiz.restart": "Neu starten", - "map.search": "Suchen" + "map.search": "Suchen", + "back": "Zurück" }), Translation(language: "NL", data: { "weather.hourly": "Volgende uren", @@ -63,7 +66,8 @@ List translations = [ "menu": "Menu", "quiz.seeResponses": "Zie de antwoorden", "quiz.restart": "Herstarten", - "map.search": "Zoeken" + "map.search": "Zoeken", + "back": "Rug" }), Translation(language: "IT", data: { "weather.hourly": "Le prossime ore", @@ -79,7 +83,8 @@ List translations = [ "menu": "Menù", "quiz.seeResponses": "Vedi le risposte", "quiz.restart": "Ricomincia", - "map.search": "Cerca" + "map.search": "Cerca", + "back": "Indietro" }), Translation(language: "ES", data: { "weather.hourly": "Próximas horas", @@ -95,7 +100,8 @@ List translations = [ "menu": "Menú", "quiz.seeResponses": "Ver las respuestas", "quiz.restart": "Reanudar", - "map.search": "Buscar" + "map.search": "Buscar", + "back": "Atrás" }), Translation(language: "PL", data: { "weather.hourly": "Następne godziny", @@ -111,7 +117,8 @@ List translations = [ "menu": "Menu", "quiz.seeResponses": "Zobacz odpowiedzi", "quiz.restart": "Uruchom ponownie", - "map.search": "Szukaj" + "map.search": "Szukaj", + "back": "Z powrotem" }), Translation(language: "CN", data: { "weather.hourly": "接下来的几个小时", @@ -127,7 +134,8 @@ List translations = [ "menu": "菜单", "quiz.seeResponses": "查看答案", "quiz.restart": "重新开始", - "map.search": "搜索" + "map.search": "搜索", + "back": "后退" }), Translation(language: "UK", data: { "weather.hourly": "Наступні години", @@ -143,7 +151,8 @@ List translations = [ "menu": "Меню", "quiz.seeResponses": "Подивіться відповіді", "quiz.restart": "Перезапустіть", - "map.search": "Шукати" + "map.search": "Шукати", + "back": "Назад" }), Translation(language: "AR", data: { "weather.hourly": "الساعات القادمة", @@ -159,6 +168,7 @@ List translations = [ "menu": "القائمة", "quiz.seeResponses": "انظر الإجابات", "quiz.restart": "إعادة تشغيل", - "map.search": "بحث" + "map.search": "بحث", + "back": "خلف" }), ]; \ No newline at end of file diff --git a/lib/Screens/MainView/main_view.dart b/lib/Screens/MainView/main_view.dart index ac25ee3..129d365 100644 --- a/lib/Screens/MainView/main_view.dart +++ b/lib/Screens/MainView/main_view.dart @@ -12,14 +12,13 @@ import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_widget_from_html/flutter_widget_from_html.dart'; import 'package:manager_api/api.dart'; +import 'package:path_provider/path_provider.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/Helpers/DatabaseHelper.dart'; import 'package:tablet_app/Helpers/ImageCustomProvider.dart'; import 'package:tablet_app/Helpers/MQTTHelper.dart'; import 'package:tablet_app/Helpers/translationHelper.dart'; -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'; @@ -27,7 +26,6 @@ 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'; -import 'package:tablet_app/Models/map-marker.dart'; import 'package:tablet_app/Models/tabletContext.dart'; import 'package:tablet_app/Screens/Menu/menu_view.dart'; import 'package:tablet_app/Screens/PDF/pdf_view.dart'; @@ -104,381 +102,95 @@ class _MainViewWidget extends State { /*if (!MQTTHelper.instance.isInstantiated) MQTTHelper.instance.connect(appContext);*/ - /*if(sectionSelected != null) { - var elementToShow; - print(sectionSelected!.type); - switch (sectionSelected!.type) { - case SectionType.Map : // MAP - elementToShow = 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()),*/ - ); - break; - case SectionType.Web : // WEB - elementToShow = WebView(section: sectionSelected); - break; - case SectionType.Video : // Video - elementToShow = VideoView(section: sectionSelected); - break; - case SectionType.Slider : - elementToShow = SliderView(section: sectionSelected); - break; - case SectionType.Menu : - elementToShow = MenuView(section: sectionSelected!, isImageBackground: isImageBackground); - break; - case SectionType.Quizz : - elementToShow = QuizzView(section: sectionSelected); - break; - case SectionType.Pdf : - elementToShow = PDFViewWidget(section: sectionSelected); - break; - case SectionType.Puzzle : - elementToShow = PuzzleView(section: sectionSelected); - break; - case SectionType.Agenda : - elementToShow = AgendaView(section: sectionSelected); - break; - /*case SectionType.article : // TODO - elementToShow = ArticleView(section: sectionSelected); - break;*/ - case SectionType.Weather : - elementToShow = WeatherView(section: sectionSelected); - break; - default: - elementToShow = Text("Ce type n'est pas supporté"); - break; - } - return Scaffold( + return Scaffold( resizeToAvoidBottomInset: false, - body: SingleChildScrollView( - child: Container( - height: size.height, - width: size.width, - color: configurationDTO.imageId == null ? configurationDTO.secondaryColor != null ? new Color(int.parse(configurationDTO.secondaryColor!.split('(0x')[1].split(')')[0], radix: 16)): kBackgroundGrey : null, - decoration: 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, configurationDTO.imageId!, 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: [ - 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, - ), - ), - ), - ), - ), - ), - ), - Container( - //width: size.width, - //color: Colors.green, - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Align( - alignment: Alignment.center, - child: HtmlWidget( - sectionSelected!.title!.firstWhere((translation) => translation.language == appContext.getContext().language).value!, - textStyle: new TextStyle(fontSize: kIsWeb ? kWebSectionTitleDetailSize : kSectionTitleDetailSize, color: textColor, fontFamily: 'Roboto'), - ) - ), - if(sectionSelected!.description!.firstWhere((translation) => translation.language == appContext.getContext().language).value != null && sectionSelected!.description!.firstWhere((translation) => translation.language == appContext.getContext().language).value!.trim().isNotEmpty) - Align( - //alignment: Alignment.center, - child: HtmlWidget( - sectionSelected!.description!.firstWhere((translation) => translation.language == appContext.getContext().language).value!, - textStyle: new TextStyle(fontSize: kIsWeb? kWebSectionDescriptionDetailSize : kSectionDescriptionDetailSize, color: 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: () { - setState(() { - sectionSelected = null; - }); - }, - 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: sectionSelected!.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,*/ + body: Container( + height: size.height, + width: size.width, + color: configurationDTO.imageId == null ? configurationDTO.secondaryColor != null ? backgroundColor : kBackgroundGrey : null, + decoration: configurationDTO.imageId != null ? BoxDecoration( + image: new DecorationImage( + fit: BoxFit.cover, + colorFilter: new ColorFilter.mode(Colors.grey.withOpacity(0.1), BlendMode.color), + image: ImageCustomProvider.getImageProvider(appContext, configurationDTO.imageId!, configurationDTO.imageSource!) + ), + ) : null, + child: Stack( + children: [ + if(currentHourDate.value != null) + ValueListenableBuilder( + valueListenable: currentHourDate, + builder: (context, value, _) { + return Positioned( + top: 0, + left: 0, child: Padding( - padding: const EdgeInsets.only(bottom: 8.0), - child: 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)) - ), - ), - ), - ),*/ - ); - } else {*/ - return Scaffold( - resizeToAvoidBottomInset: false, - body: Container( - height: size.height, - width: size.width, - color: configurationDTO.imageId == null ? configurationDTO.secondaryColor != null ? backgroundColor : kBackgroundGrey : null, - decoration: configurationDTO.imageId != null ? BoxDecoration( - image: new DecorationImage( - fit: BoxFit.cover, - colorFilter: new ColorFilter.mode(Colors.grey.withOpacity(0.1), BlendMode.color), - image: ImageCustomProvider.getImageProvider(appContext, configurationDTO.imageId!, configurationDTO.imageSource!) - ), - ) : null, - child: Stack( - children: [ - if(currentHourDate.value != null) - ValueListenableBuilder( - valueListenable: currentHourDate, - builder: (context, value, _) { - return Positioned( - top: 0, - left: 0, - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - if(value != null && configurationDTO.isHour!) - Text(DateFormat('HH:mm').format(value), style: TextStyle(fontSize: 20, color: textColor)), - if(value != null && configurationDTO.isDate!) - if(appContext.getContext().language.toString().toUpperCase() == "EN") - Text(DateFormat('MM/dd').format(value), style: TextStyle(fontSize: 15, color: textColor)), - if(value != null && configurationDTO.isDate!) - if(appContext.getContext().language.toString().toUpperCase() != "EN") - Text(DateFormat('dd/MM').format(value), style: TextStyle(fontSize: 15, color: textColor)), - ], - ), - ) - ); - }, - ), - LanguageSelection(size: size), - Center( - child: Container( - height: configurationDTO.screenPercentageSectionsMainPage != null ? size.height * (configurationDTO.screenPercentageSectionsMainPage! / 100) : size.height * 0.85, - width: size.width * 0.9, - child: isInit ? FutureBuilder( - future: getSections(size, appContext), - builder: (context, AsyncSnapshot snapshot) { - if (snapshot.connectionState == ConnectionState.done) { - if (snapshot.data == null) { - // Show select config - return Text(""); - } - else { - return getGridSections(appContext, textColor); - } - } else if (snapshot.connectionState == ConnectionState.none) { - return Text("No data"); - } else { - return Center( - child: Container( - child: LoadingCommon() - ) - ); - } - } - ) : getGridSections(appContext, textColor), - ), + padding: const EdgeInsets.all(8.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if(value != null && configurationDTO.isHour!) + Text(DateFormat('HH:mm').format(value), style: TextStyle(fontSize: 20, color: textColor)), + if(value != null && configurationDTO.isDate!) + if(appContext.getContext().language.toString().toUpperCase() == "EN") + Text(DateFormat('MM/dd').format(value), style: TextStyle(fontSize: 15, color: textColor)), + if(value != null && configurationDTO.isDate!) + if(appContext.getContext().language.toString().toUpperCase() != "EN") + Text(DateFormat('dd/MM').format(value), style: TextStyle(fontSize: 15, color: textColor)), + ], + ), + ) + ); + }, ), - /*if(configurationDTO.weatherCity != null && configurationDTO.weatherCity!.length > 2 && configurationDTO.weatherResult != null) - Positioned( - bottom: 0, - left: 0, - child: Padding( - padding: const EdgeInsets.all(5.0), - child: Builder( - builder: (context) { - Map weatherResultInJson = jsonDecode(configurationDTO.weatherResult!); - - WeatherData weatherDataResult = WeatherData.fromJson(weatherResultInJson); - return WeatherView(weatherData: weatherDataResult); + LanguageSelection(size: size), + Center( + child: Container( + height: configurationDTO.screenPercentageSectionsMainPage != null ? size.height * (configurationDTO.screenPercentageSectionsMainPage! / 100) : size.height * 0.85, + width: size.width * 0.9, + child: isInit ? FutureBuilder( + future: getSections(size, appContext), + builder: (context, AsyncSnapshot snapshot) { + if (snapshot.connectionState == ConnectionState.done) { + if (snapshot.data == null) { + // Show select config + return Text(""); } - ), - ))*/ - ]), - ), - ); - //} + else { + return getGridSections(appContext, textColor); + } + } else if (snapshot.connectionState == ConnectionState.none) { + return Text("No data"); + } else { + return Center( + child: Container( + child: LoadingCommon() + ) + ); + } + } + ) : getGridSections(appContext, textColor), + ), + ), + /*if(configurationDTO.weatherCity != null && configurationDTO.weatherCity!.length > 2 && configurationDTO.weatherResult != null) + Positioned( + bottom: 0, + left: 0, + child: Padding( + padding: const EdgeInsets.all(5.0), + child: Builder( + builder: (context) { + Map weatherResultInJson = jsonDecode(configurationDTO.weatherResult!); + + WeatherData weatherDataResult = WeatherData.fromJson(weatherResultInJson); + return WeatherView(weatherData: weatherDataResult); + } + ), + ))*/ + ]), + ), + ); } Future getCurrentConfiguration(dynamic appContext) async { @@ -588,12 +300,11 @@ class _MainViewWidget extends State { onTap: () { setState(() { //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)); + return SectionPageDetail(configurationDTO: configurationDTO, sectionDTO: sectionsLocal![index], textColor: textColor, isImageBackground: isImageBackground, elementToShow: getContent(tabletAppContext, sectionsLocal![index], isImageBackground), isFromMenu: false); }, ),// For pushAndRemoveUntil ); @@ -691,7 +402,7 @@ boxDecoration(AppContext appContext, SectionDTO section, bool isSelected) { ); } -Future>> getByteIcons(SectionDTO section) async { +Future>> getByteIcons(TabletAppContext tabletAppContext, SectionDTO section) async { var mapDTO = MapDTO.fromJson(jsonDecode(section.data!)); var selectedMarkerIcon; @@ -700,8 +411,14 @@ Future>> getByteIcons(SectionDTO section) async { 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); + File? localIcon = await _checkIfLocalResourceExists(tabletAppContext, mapDTO.iconResourceId!); + if(localIcon == null) { + final ByteData imageData = await NetworkAssetBundle(Uri.parse(mapDTO.iconSource!)).load(""); + selectedMarkerIcon = await getBytesFromAsset(imageData, 50); + } else { + Uint8List bytes = await localIcon.readAsBytes(); + selectedMarkerIcon = await getBytesFromAsset(ByteData.view(bytes.buffer), 50); + } } } else { // Icône par défaut @@ -713,14 +430,21 @@ Future>> getByteIcons(SectionDTO section) async { icons.add({'id': null, 'icon': selectedMarkerIcon}); - mapDTO!.categories!.forEach((cat) async { - if (cat.iconUrl != null) { + // Utiliser Future.forEach() pour itérer de manière asynchrone sur la liste des catégories + await Future.forEach(mapDTO!.categories!, (cat) async { + if (cat.iconUrl != null && cat.iconResourceId != 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); + File? localIcon = await _checkIfLocalResourceExists(tabletAppContext, cat.iconResourceId!); + if(localIcon == null) { + final ByteData imageData = await NetworkAssetBundle(Uri.parse(cat.iconUrl!)).load(""); + categoryIcon = await getBytesFromAsset(imageData, 50); + } else { + Uint8List bytes = await localIcon.readAsBytes(); + categoryIcon = await getBytesFromAsset(ByteData.view(bytes.buffer), 50); + } } icons.add({'id': cat.id, 'icon': categoryIcon}); } @@ -729,14 +453,29 @@ Future>> getByteIcons(SectionDTO section) async { return icons; } +Future _checkIfLocalResourceExists(TabletAppContext tabletAppContext, String iconId) async { + try { + Directory? appDocumentsDirectory = Platform.isIOS ? await getApplicationDocumentsDirectory() : await getDownloadsDirectory(); + String localPath = appDocumentsDirectory!.path; + Directory configurationDirectory = Directory('$localPath/${tabletAppContext.configuration!.id}'); + List fileList = configurationDirectory.listSync(); + + if(fileList.any((fileL) => fileL.uri.pathSegments.last.contains(iconId))) { + File file = File(fileList.firstWhere((fileL) => fileL.uri.pathSegments.last.contains(iconId)).path); + return file; + } + } catch(e) { + print("ERROR _checkIfLocalResourceExists CachedCustomResource"); + print(e); + } + return null; +} + 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.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(); + return (await fi.image.toByteData(format: ui.ImageByteFormat.png))!.buffer.asUint8List(); } Uint8List resizeImage(Uint8List data, int width) { @@ -747,18 +486,14 @@ Uint8List resizeImage(Uint8List data, int width) { return resizedData; } -Widget getContent(SectionDTO sectionSelected, bool isImageBackground) { +Widget getContent(TabletAppContext tabletAppContext, SectionDTO sectionSelected, bool isImageBackground) { switch (sectionSelected.type) { case SectionType.Map : // MAP return ChangeNotifierProvider( create: (_) => - MapContext(new MapMarker( - latitude: null, - longitude: null, - title: '', - description: '')), + MapContext(null), child: FutureBuilder( - future: getByteIcons(sectionSelected), + future: getByteIcons(tabletAppContext, sectionSelected), builder: (context, AsyncSnapshot snapshot) { if (snapshot.connectionState == ConnectionState.done) { return MapViewWidget(section: sectionSelected, icons: snapshot.data); @@ -785,7 +520,7 @@ Widget getContent(SectionDTO sectionSelected, bool isImageBackground) { case SectionType.Slider : return SliderView(section: sectionSelected); case SectionType.Menu : - return MenuView(section: sectionSelected!, isImageBackground: isImageBackground); + return MenuView(section: sectionSelected, isImageBackground: isImageBackground); case SectionType.Quizz : return QuizzView(section: sectionSelected); case SectionType.Pdf : @@ -802,6 +537,4 @@ Widget getContent(SectionDTO sectionSelected, bool isImageBackground) { 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 index 253e093..c9a5c16 100644 --- a/lib/Screens/MainView/section_page_detail.dart +++ b/lib/Screens/MainView/section_page_detail.dart @@ -13,6 +13,7 @@ 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/MainView/main_view.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; @@ -25,6 +26,7 @@ class SectionPageDetail extends StatefulWidget { final Uint8List? selectedMarkerIcon; final Color textColor; final bool isImageBackground; + final bool isFromMenu; final Widget elementToShow; const SectionPageDetail({ Key? key, @@ -33,6 +35,7 @@ class SectionPageDetail extends StatefulWidget { this.selectedMarkerIcon, required this.textColor, required this.isImageBackground, + required this.isFromMenu, required this.elementToShow, }) : super(key: key); @@ -155,9 +158,21 @@ class _SectionPageDetailState extends State { splashColor: kBackgroundColor, onPressed: () { Navigator.pop(context); + /*Navigator.of(context).pushReplacement( + PageRouteBuilder( + transitionDuration: Duration(milliseconds: 500), // Durée de la transition en millisecondes + pageBuilder: (_, __, ___) => MainViewWidget(), // Page précédente + transitionsBuilder: (_, animation, __, child) { + return FadeTransition( + opacity: animation, + child: child, + ); + }, + ), + );*/ }, icon: Icon(Icons.arrow_back, color: Colors.grey), - label: Text(TranslationHelper.getFromLocale("menu", appContext.getContext()), style: TextStyle(color: Colors.black)) + label: Text(TranslationHelper.getFromLocale(widget.isFromMenu ? "back" : "menu", appContext.getContext()), style: TextStyle(color: Colors.black)) ), ), ), diff --git a/lib/Screens/Map/geo_point_filter.dart b/lib/Screens/Map/geo_point_filter.dart index f7812ea..1e6ba71 100644 --- a/lib/Screens/Map/geo_point_filter.dart +++ b/lib/Screens/Map/geo_point_filter.dart @@ -66,6 +66,21 @@ class _GeoPointFilterState extends State { List buildTreeNodes(List categories, List geoPoints) { List nodes = []; + // Pour chaque point sans categorie, créer un noeud + for(var pointWithoutCat in geoPoints.where((gp) => gp.categorieId == null && gp.categorie == null)) + { + TreeNode nodeWithoutCat = TreeNode( + id: int.parse(pointWithoutCat.latitude!.substring(0,10).replaceAll(".", "")+pointWithoutCat.longitude!.substring(0,10).replaceAll(".", "")), + title: parse(pointWithoutCat.title!.firstWhere((l) => l.language == widget.language).value!).documentElement!.text, + children: [], + checked: true, // default true + show: false, + pid: 0, + commonID: 0, + ); + nodes.add(nodeWithoutCat); + } + // Pour chaque catégorie, créez un nœud parent for (var category in categories) { TreeNode categoryNode = TreeNode( @@ -79,7 +94,7 @@ class _GeoPointFilterState extends State { ); // Ajoutez les géopoints correspondant à cette catégorie en tant qu'enfants du nœud parent - for (var geoPoint in geoPoints) { + for (var geoPoint in geoPoints.where((gp) => gp.categorie != null || gp.categorieId != null)) { if (geoPoint.categorieId == category.id) { TreeNode geoPointNode = TreeNode( id: int.parse(geoPoint.latitude!.substring(0,10).replaceAll(".", "")+geoPoint.longitude!.substring(0,10).replaceAll(".", "")), @@ -97,6 +112,8 @@ class _GeoPointFilterState extends State { nodes.add(categoryNode); } + nodes.sort((a, b) => a.title.compareTo(b.title)); + return nodes; } @@ -125,6 +142,10 @@ class _GeoPointFilterState extends State { checkedGeoPoints.add(widget.geoPoints.firstWhere((point) => int.parse(point.latitude!.substring(0,10).replaceAll(".", "")+point.longitude!.substring(0,10).replaceAll(".", "")) == childNode.id)); } } + } else { + if(node.checked) { + checkedGeoPoints.add(widget.geoPoints.firstWhere((point) => int.parse(point.latitude!.substring(0,10).replaceAll(".", "")+point.longitude!.substring(0,10).replaceAll(".", "")) == node.id)); + } } } @@ -195,7 +216,7 @@ class _GeoPointFilterState extends State { decoration: InputDecoration( labelText: TranslationHelper.getFromLocale("map.search", appContext.getContext()), labelStyle: TextStyle( - color: focusNode.hasFocus ? primaryColor : Colors.black + color: Colors.black ), focusColor: primaryColor, focusedBorder: OutlineInputBorder( @@ -203,7 +224,7 @@ class _GeoPointFilterState extends State { borderSide: BorderSide(color: primaryColor)), //labelStyle: TextStyle(color: primaryColor), suffixIcon: IconButton( - icon: _searchController.text.isNotEmpty ? Icon(Icons.close) : Icon(Icons.search), + icon: _searchController.text.isNotEmpty ? Icon(Icons.close, color: primaryColor) : Icon(Icons.search, color: primaryColor), onPressed: () { if(_searchController.text.isNotEmpty) { _searchController.text = ""; @@ -226,8 +247,8 @@ class _GeoPointFilterState extends State { 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), + padding: const EdgeInsets.only(top: 1.5, right: 1.1), + child: Icon(_isExpanded ? Icons.expand_more : Icons.chevron_left, color: primaryColor), ), ), ), @@ -237,29 +258,24 @@ class _GeoPointFilterState extends State { ValueListenableBuilder( valueListenable: _searchTextNotifier, builder: (context, value, _) { - return Container( - //color: Colors.greenAccent, - height: _isExpanded ? widget.provider == MapProvider.Google ? size.height * 0.68 : size.height * 0.65 : 0, - width: size.width * 0.3, - child: GenerateTree( - data: _filteredNodes, - selectOneToAll: true, - textColor: Colors.black, - onChecked: (node, checked, commonID) { - if(checked) { - //node. - //var test = - //selectedGeoPoints.add(); - } - print('isChecked : $checked'); - print('common Node ID : ${commonID}'); - print('children node data : ${node.children.map((e) => '${e.title}')}'); - // Todo update selection - sendFilteredGeoPoint(); - }, - checkBoxColor: primaryColor, - childrenPadding: EdgeInsets.only(left: 20, top: 10, right: 0, bottom: 10), - ), + return Stack( + children: [ + Container( + //color: Colors.greenAccent, + height: _isExpanded ? widget.provider == MapProvider.Google ? size.height * 0.68 : size.height * 0.65 : 0, + width: size.width * 0.3, + child: GenerateTree( + data: _filteredNodes, + selectOneToAll: true, + textColor: Colors.black, + onChecked: (node, checked, commonID) { + sendFilteredGeoPoint(); + }, + checkBoxColor: primaryColor, + childrenPadding: EdgeInsets.only(left: 20, top: 10, right: 0, bottom: 10), + ), + ), + ], ); } ), diff --git a/lib/Screens/Map/google_map_view.dart b/lib/Screens/Map/google_map_view.dart index 1867544..d16fed0 100644 --- a/lib/Screens/Map/google_map_view.dart +++ b/lib/Screens/Map/google_map_view.dart @@ -17,11 +17,13 @@ import 'package:tablet_app/constants.dart'; class GoogleMapView extends StatefulWidget { final MapDTO mapDTO; + final List geoPoints; final List> icons; final String? language; const GoogleMapView({ Key? key, required this.mapDTO, + required this.geoPoints, required this.icons, this.language, }) : super(key: key); @@ -35,58 +37,53 @@ class _GoogleMapViewState extends State { Completer _controller = Completer(); Set markers = {}; List? pointsToShow = []; - List? selectedCategories = []; + //List? selectedCategories = []; bool init = false; Set getMarkers(language, mapContext) { markers = {}; + int i = 0; pointsToShow!.forEach((point) { var textSansHTML = parse(point.title!.firstWhere((translation) => translation.language == language).value); - var mapMarker = new MapMarker( + point.id = i; + /*var mapMarker = new MapMarker( id: point.id, title: parse(textSansHTML.body!.text).documentElement!.text, description: point.description!.firstWhere((translation) => translation.language == language).value, longitude: point.longitude, latitude: point.latitude, contents: point.contents - ); - if (mapMarker.latitude != null && mapMarker.longitude != null) { + );*/ + if (point.latitude != null && point.longitude != null) { + var 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,; markers.add(Marker( draggable: false, - markerId: MarkerId(parse(textSansHTML.body!.text).documentElement!.text + mapMarker.latitude! + mapMarker.longitude!), + markerId: MarkerId(parse(textSansHTML.body!.text).documentElement!.text + point.latitude! + point.longitude!), position: LatLng( - double.tryParse(mapMarker.latitude!)!, - double.tryParse(mapMarker.longitude!)!, + double.tryParse(point.latitude!)!, + double.tryParse(point.longitude!)!, ), - 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, + icon: icon, //widget.selectedMarkerIcon, //widget.selectedMarkerIcon != null ? BitmapDescriptor.fromBytes(widget.selectedMarkerIcon!) : BitmapDescriptor.defaultMarker, /*icon: BitmapDescriptor.defaultMarkerWithHue( BitmapDescriptor.hueYellow, ),*/ onTap: () { //setState(() { - mapContext.setSelectedMarker( - new MapMarker( - title: mapMarker.title, - contents: mapMarker.contents, - description: mapMarker.description, - longitude: mapMarker.longitude, - latitude: mapMarker.latitude, - ) - ); + mapContext.setSelectedPoint(point); //}); }, infoWindow: InfoWindow.noText)); } + i++; }); return markers; } @override void initState() { - pointsToShow = widget.mapDTO!.points; - selectedCategories = widget.mapDTO!.categories!.map((categorie) => categorie.label!.firstWhere((element) => element.language == widget.language).value!).toList(); + //selectedCategories = widget.mapDTO.categories!.map((cat) => cat.label!.firstWhere((element) => element.language == widget.language).value!).toList(); super.initState(); } @@ -103,18 +100,20 @@ class _GoogleMapViewState extends State { TabletAppContext tabletAppContext = appContext.getContext() as TabletAppContext; Size size = MediaQuery.of(context).size; - if(!init) { - print("getmarkers in build"); + pointsToShow = widget.geoPoints; + + /*if(!init) { + print("getmarkers in build");*/ getMarkers(widget.language, mapContext); - init = true; - } + /* init = true; + }*/ //MapTypeApp? mapTypeApp = MapTypeApp.fromJson(widget.mapDTO!.mapType!.value); //print(mapTypeApp.toString()); MapType type = MapType.hybrid; //if(kIsWeb) { - if(widget.mapDTO!.mapType != null) { - switch(widget.mapDTO!.mapType!.value) { + if(widget.mapDTO.mapType != null) { + switch(widget.mapDTO.mapType!.value) { case 0: type = MapType.none; break; @@ -148,8 +147,8 @@ class _GoogleMapViewState extends State { mapToolbarEnabled: false, indoorViewEnabled: false, initialCameraPosition: CameraPosition( - target: LatLng(50.465503, 4.865105), //TODO add element in manager // MDLF 50.416639, 4.879169 / Namur 50.465503, 4.865105 - zoom: widget.mapDTO!.zoom != null ? widget.mapDTO!.zoom!.toDouble() : 18, + target: widget.mapDTO.longitude != null && widget.mapDTO.latitude != null ? LatLng(double.tryParse(widget.mapDTO.latitude!)!, double.tryParse(widget.mapDTO.longitude!)!) : LatLng(50.465503, 4.865105) , // MDLF 50.416639, 4.879169 / Namur 50.465503, 4.865105 + zoom: widget.mapDTO.zoom != null ? widget.mapDTO.zoom!.toDouble() : 18, ), onMapCreated: (GoogleMapController controller) { if(kIsWeb) { @@ -162,14 +161,7 @@ class _GoogleMapViewState extends State { onTap: (LatLng location) { //setState(() { print(location); - mapContext.setSelectedMarker( - new MapMarker( - title: '', - description: '', - contents: null, - longitude: null, - latitude: null - )); + mapContext.setSelectedPoint(null); // }); }, ), diff --git a/lib/Screens/Map/map_box_view.dart b/lib/Screens/Map/map_box_view.dart index cb73912..ba327db 100644 --- a/lib/Screens/Map/map_box_view.dart +++ b/lib/Screens/Map/map_box_view.dart @@ -35,7 +35,7 @@ class MapBoxView extends StatefulWidget { } class AnnotationClickListener extends mapBox.OnPointAnnotationClickListener { - late List markersList; + late List markersList; late MapContext mapContext; AnnotationClickListener({ @@ -46,8 +46,8 @@ class AnnotationClickListener extends mapBox.OnPointAnnotationClickListener { @override void onPointAnnotationClick(mapBox.PointAnnotation annotation) { try{ - var markerToShow = markersList.firstWhere((ml) => "${ml.title}${ml.latitude}${ml.longitude}" == annotation.textField); - mapContext.setSelectedMarker(markerToShow); + var markerToShow = markersList.firstWhere((ml) => "${parse(ml.title!.first.value).documentElement!.text}${ml.latitude}${ml.longitude}" == annotation.textField); + mapContext.setSelectedPoint(markerToShow); } catch(e) { print("ISSSUE setSelectedMarker"); print(e); @@ -63,25 +63,28 @@ class _MapBoxViewState extends State { createPoints() { var options = []; int i = 0; + markersList = []; pointsToShow!.forEach((point) { var textSansHTML = parse(point.title!.firstWhere((translation) => translation.language == widget.language).value); - var mapMarker = new MapMarker( + point.id = i; + point.title = point.title!.where((t) => t.language == widget.language).toList(); + /*var mapMarker = new MapMarker( id: i, title: parse(textSansHTML.body!.text).documentElement!.text, description: point.description!.firstWhere((translation) => translation.language == widget.language).value, longitude: point.longitude, latitude: point.latitude, contents: point.contents - ); - markersList.add(mapMarker); + );*/ + markersList.add(point); options.add(mapBox.PointAnnotationOptions( geometry: mapBox.Point( coordinates: mapBox.Position( - double.tryParse(mapMarker.longitude!)!, - double.tryParse(mapMarker.latitude!)!, + double.tryParse(point.longitude!)!, + double.tryParse(point.latitude!)!, )).toJson(), iconSize: 1.3, - textField: "${parse(textSansHTML.body!.text).documentElement!.text}${mapMarker.latitude}${mapMarker.longitude}", + textField: "${parse(textSansHTML.body!.text).documentElement!.text}${point.latitude}${point.longitude}", textOpacity: 0.0, iconOffset: [0.0, 0.0], symbolSortKey: 10, @@ -181,10 +184,10 @@ class _MapBoxViewState extends State { }, onTapListener: (listener) { // close on tap - mapContext.setSelectedMarker(new MapMarker(longitude: null, latitude: null, title: '', contents: null, description: '')); + mapContext.setSelectedPoint(null); }, cameraOptions: mapBox.CameraOptions( - center: mapBox.Point(coordinates: mapBox.Position(4.865105, 50.465503)).toJson(), //TODO add element in manager // MDLF 50.416639, 4.879169 / Namur 50.465503, 4.865105 + center: mapBox.Point(coordinates: widget.mapDTO!.longitude != null && widget.mapDTO!.latitude != null ? mapBox.Position(double.tryParse(widget.mapDTO!.longitude!)!, double.tryParse(widget.mapDTO!.latitude!)!) : mapBox.Position(4.865105, 50.465503)).toJson(),//TODO add element in manager // MDLF 50.416639, 4.879169 / Namur 50.465503, 4.865105 zoom: widget.mapDTO!.zoom != null ? widget.mapDTO!.zoom!.toDouble() : 12), ) ), diff --git a/lib/Screens/Map/map_context.dart b/lib/Screens/Map/map_context.dart index 5c9fd18..80e3796 100644 --- a/lib/Screens/Map/map_context.dart +++ b/lib/Screens/Map/map_context.dart @@ -1,14 +1,14 @@ import 'package:flutter/material.dart'; -import 'package:tablet_app/Models/map-marker.dart'; +import 'package:manager_api/api.dart'; class MapContext with ChangeNotifier { - MapMarker _selectedMarker; + GeoPointDTO? _selectedPoint; - MapContext(this._selectedMarker); + MapContext(this._selectedPoint); - getSelectedMarker() => _selectedMarker; - setSelectedMarker(MapMarker selectedMarker) { - _selectedMarker = selectedMarker; + getSelectedPoint() => _selectedPoint; + setSelectedPoint(GeoPointDTO? selectedPoint) { + _selectedPoint = selectedPoint; notifyListeners(); } diff --git a/lib/Screens/Map/map_view.dart b/lib/Screens/Map/map_view.dart index 5fa793e..7819151 100644 --- a/lib/Screens/Map/map_view.dart +++ b/lib/Screens/Map/map_view.dart @@ -23,7 +23,7 @@ import 'google_map_view.dart'; //import 'package:image/image.dart' as IMG; //Set markers = {}; -List markersList = []; +List markersList = []; class MapViewWidget extends StatefulWidget { final SectionDTO section; @@ -96,12 +96,12 @@ class _MapViewWidget extends State { builder: (context, value, _) { switch(mapDTO!.mapProvider) { case MapProvider.Google: - return GoogleMapView(language: appContext.getContext().language, mapDTO: mapDTO!, icons: widget.icons); + return GoogleMapView(language: appContext.getContext().language, geoPoints: value, 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); + return GoogleMapView(language: appContext.getContext().language, geoPoints: value, mapDTO: mapDTO!, icons: widget.icons); } } ), @@ -109,7 +109,7 @@ class _MapViewWidget extends State { language: tabletAppContext.language!, geoPoints: mapDTO!.points!, categories: mapDTO!.categories!, - provider: mapDTO!.mapProvider!, + provider: mapDTO!.mapProvider == null ? MapProvider.Google : mapDTO!.mapProvider!, filteredPoints: (value) { _geoPoints.value = value!; }), diff --git a/lib/Screens/Map/marker_view.dart b/lib/Screens/Map/marker_view.dart index 59e0089..148e62f 100644 --- a/lib/Screens/Map/marker_view.dart +++ b/lib/Screens/Map/marker_view.dart @@ -1,17 +1,22 @@ +import 'package:auto_size_text/auto_size_text.dart'; import 'package:cached_network_image/cached_network_image.dart'; import 'package:carousel_slider/carousel_slider.dart'; +import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_widget_from_html/flutter_widget_from_html.dart'; import 'package:manager_api/api.dart'; import 'package:photo_view/photo_view.dart'; import 'package:provider/provider.dart'; +import 'package:qr_flutter/qr_flutter.dart'; +import 'package:tablet_app/Components/loading_common.dart'; import 'package:tablet_app/Components/show_element_for_resource.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/Quizz/quizz_view.dart'; import 'package:tablet_app/app_context.dart'; +import 'package:html/parser.dart' show parse; import '../../constants.dart'; import 'map_context.dart'; @@ -45,31 +50,31 @@ class _MarkerInfoWidget extends State { final mapContext = Provider.of(context); final appContext = Provider.of(context); TabletAppContext tabletAppContext = appContext.getContext() as TabletAppContext; + var language = tabletAppContext.language; + GeoPointDTO? selectedPoint = mapContext.getSelectedPoint() as GeoPointDTO?; - Size sizeMarker = Size(size.width * 0.42, size.height * 0.8); - return new AnimatedPositioned( - duration: const Duration(milliseconds: 1500), - curve: Curves.easeInOutSine, - left: 25, // 140 - top: 10, // 150 + Color primaryColor = new Color(int.parse(tabletAppContext.configuration!.primaryColor!.split('(0x')[1].split(')')[0], radix: 16)); + + Size sizeMarker = Size(size.width * 0.9, size.height * 0.8); + return Center( child: Visibility( - visible: (mapContext.getSelectedMarker() as MapMarker).longitude != null, + visible: selectedPoint != null, child: Container( width: sizeMarker.width, height: sizeMarker.height, margin: EdgeInsets.symmetric(vertical: 3, horizontal: 4), decoration: BoxDecoration( - color: kBackgroundLight, // Colors.amberAccent //kBackgroundLight, - shape: BoxShape.rectangle, + color: kBackgroundColor, // Colors.amberAccent //kBackgroundLight, + //shape: BoxShape.rectangle, borderRadius: BorderRadius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 10.0), - boxShadow: [ + /*boxShadow: [ BoxShadow( color: kBackgroundSecondGrey, spreadRadius: 0.5, blurRadius: 1.1, offset: Offset(0, 1.1), // changes position of shadow ), - ], + ],*/ ), child: Stack( children: [ @@ -79,18 +84,18 @@ class _MarkerInfoWidget extends State { child: InkWell( onTap: () { setState(() { - mapContext.setSelectedMarker(new MapMarker(longitude: null, latitude: null, title: '', contents: null, description: '')); + mapContext.setSelectedPoint(null); }); }, child: Container( width: 50, height: 50, decoration: BoxDecoration( - color: kMainGrey, + color: kBackgroundGrey, shape: BoxShape.circle, boxShadow: [ BoxShadow( - color: kMainGrey, + color: kBackgroundGrey, spreadRadius: 0.5, blurRadius: 1.1, offset: Offset(0, 1.1), // changes position of shadow @@ -105,7 +110,211 @@ class _MarkerInfoWidget extends State { ), ), ), - Align( + if(selectedPoint != null) + Row( + children: [ + selectedPoint.imageResourceId != null && selectedPoint.imageUrl != null ? ClipRRect( + borderRadius: BorderRadius.only(topLeft: Radius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 20.0), bottomLeft: Radius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 20.0)), + child: Container( + child: Center( + child: Container( + decoration: BoxDecoration( + border: Border(right: BorderSide(width: 0.05, color: kMainGrey)), + color: Colors.grey, + ), + width: size.width * 0.17, + height: size.height, + child: CachedNetworkImage( + imageUrl: selectedPoint.imageUrl!, + width: size.width, + fit: BoxFit.cover, + progressIndicatorBuilder: (context, url, downloadProgress) { + return Center( + child: SizedBox( + width: 50, + height: 50, + child: LoadingCommon(), + ), + ); + }, + errorWidget: (context, url, error) => Icon(Icons.error), + ), + ), + ) + ), + ): SizedBox(), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(top: 8.0, left: 15.0), + child: Container( + //color: Colors.green, + height: size.height * 0.06, + width: size.width * 0.65, + child: HtmlWidget( + selectedPoint.title!.firstWhere((t) => t.language == language).value!, + textStyle: TextStyle(fontSize: 23.0), + ), + ), + ), + Row( + children: [ + Padding( + padding: const EdgeInsets.only(left: 15), + child: Container( + height: size.height * 0.7, + width: size.width * 0.38, + decoration: BoxDecoration( + color: kBackgroundLight, + borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 20.0)) + ), + child: Padding( + padding: const EdgeInsets.only(left: 20, right: 10, bottom: 10, top: 15), + child: Scrollbar( + thumbVisibility: true, + thickness: 2.0, + child: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + if(selectedPoint.description!.any((d) => d.language == language) && selectedPoint.description!.firstWhere((d) => d.language == language).value != null && selectedPoint.description!.firstWhere((d) => d.language == language).value!.trim().length > 0) + HtmlWidget( + selectedPoint.description!.firstWhere((d) => d.language == language).value!, + customStylesBuilder: (element) { + return {'text-align': 'left'}; + }, + textStyle: TextStyle(fontSize: kDescriptionSize), + ), + ], + ), + ), + ), + ), + ), + ), + ), + SizedBox( + width: size.width * 0.32, + height: size.height * 0.7, + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Container( + //color: Colors.green, + height: size.height * 0.35, + child: CarouselSlider( + carouselController: sliderController, + options: CarouselOptions( + onPageChanged: (int index, CarouselPageChangedReason reason) { + currentIndex.value = index + 1; + }, + height: size.height *0.33, + enlargeCenterPage: true, + pageSnapping: true, + reverse: false, + ), + items: selectedPoint.contents!.map((ContentGeoPoint i) { + return Builder( + builder: (BuildContext context) { + AppContext appContext = Provider.of(context); + var resourcetoShow = getElementForResource(context, appContext, i, true); + return resourcetoShow; + }, + ); + }).toList(), + ), + ), + Container( + //color: Colors.yellow, + height: size.height * 0.33, + child: Padding( + padding: const EdgeInsets.only(top: 10.0), + child: Column( + children: [ + selectedPoint.prices != null && selectedPoint.prices!.isNotEmpty && selectedPoint.prices!.any((d) => d.language == language) && selectedPoint.prices!.firstWhere((d) => d.language == language).value != null && selectedPoint.prices!.firstWhere((d) => d.language == language).value!.trim().length > 0 ? Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Icon(Icons.price_change_outlined, color: primaryColor, size: 13), + Padding( + padding: const EdgeInsets.all(4.0), + child: Text(parse(selectedPoint.prices!.firstWhere((p) => p.language == language).value!).documentElement!.text, style: TextStyle(fontSize: 12)), + ) + ], + ): SizedBox(), + selectedPoint.phone != null && selectedPoint.phone!.isNotEmpty && selectedPoint.phone!.any((d) => d.language == language) && selectedPoint.phone!.firstWhere((d) => d.language == language).value != null && selectedPoint.phone!.firstWhere((d) => d.language == language).value!.trim().length > 0 ? Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Icon(Icons.phone, color: primaryColor, size: 13), + Padding( + padding: const EdgeInsets.all(4.0), + child: Text(parse(selectedPoint.phone!.firstWhere((p) => p.language == language).value!).documentElement!.text, style: TextStyle(fontSize: 12)), + ) + ], + ): SizedBox(), + selectedPoint.email != null && selectedPoint.email!.isNotEmpty && selectedPoint.email!.any((d) => d.language == language) && selectedPoint.email!.firstWhere((d) => d.language == language).value != null && selectedPoint.email!.firstWhere((d) => d.language == language).value!.trim().length > 0 ? Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Icon(Icons.email, color: primaryColor, size: 13), + Padding( + padding: const EdgeInsets.all(4.0), + child: SizedBox( + width: size.width*0.25, + child: AutoSizeText(parse(selectedPoint.email!.firstWhere((p) => p.language == language).value!).documentElement!.text, style: TextStyle(fontSize: 12), maxLines: 3) + ), + ) + ], + ): SizedBox(), + selectedPoint.site != null && selectedPoint.site!.isNotEmpty && selectedPoint.site!.any((d) => d.language == language) && selectedPoint.site!.firstWhere((d) => d.language == language).value != null && selectedPoint.site!.firstWhere((d) => d.language == language).value!.trim().length > 0 ? Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Icon(Icons.public, color: primaryColor, size: 13), + Padding( + padding: const EdgeInsets.all(4.0), + child: SizedBox( + width: size.width*0.25, + child: AutoSizeText(parse(selectedPoint.site!.firstWhere((p) => p.language == language).value!).documentElement!.text, style: TextStyle(fontSize: 12), maxLines: 3) + ), + ) + ], + ): SizedBox(), + selectedPoint.site != null && selectedPoint.site!.isNotEmpty && selectedPoint.site!.any((d) => d.language == language) && selectedPoint.site!.firstWhere((d) => d.language == language).value != null && selectedPoint.site!.firstWhere((d) => d.language == language).value!.trim().length > 0 ? Expanded( + child: Center( + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Container( + width: size.width *0.1, + height: 120, + child: QrImageView( + padding: EdgeInsets.only(left: 5.0, top: 5.0, bottom: 5.0, right: 5.0), + data: parse(selectedPoint.site!.firstWhere((p) => p.language == language).value!).documentElement!.text, + version: QrVersions.auto, + size: 50.0, + ), + ), + ), + ), + ): SizedBox(), + ], + ), + ), + ), + ], + ), + ), + ) + ], + ) + ], + ), + ], + ), + /*Align( alignment: Alignment.topCenter, child: Padding( padding: const EdgeInsets.only(top: 20), @@ -250,54 +459,128 @@ class _MarkerInfoWidget extends State { ], ), ), - ), + ),*/ ]) ), - ) + ), ); } } -getElementForResource(BuildContext context, AppContext appContext, ContentGeoPoint i) { +getElementForResource(BuildContext context, AppContext appContext, ContentGeoPoint i, bool addFullScreen) { var widgetToInclude; - final appContext = Provider.of(context); + Size size = MediaQuery.of(context).size; TabletAppContext tabletAppContext = appContext.getContext() as TabletAppContext; switch(i.resourceType) { case ResourceType.Image: case ResourceType.ImageUrl: - widgetToInclude = AspectRatio( - aspectRatio: 16 / 9, - child: ClipRect( - child: i.resourceUrl != null ? PhotoView( - imageProvider: ImageCustomProvider.getImageProvider(appContext, i.resourceId!, i.resourceUrl!), - minScale: PhotoViewComputedScale.contained * 0.8, - maxScale: PhotoViewComputedScale.contained * 3.0, - backgroundDecoration: BoxDecoration( - color: kBackgroundSecondGrey, - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 15.0), + widgetToInclude = GestureDetector( + onTap: () { + if(addFullScreen) { + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 20.0)) + ), + contentPadding: EdgeInsets.zero, + // title: Text(eventAgenda.name!), + content: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 20.0)), + color: kBackgroundColor, + ), + height: size.height * 0.8, + width: size.width * 0.8, + child: Container( + decoration: BoxDecoration( + //color: Colors.yellow, + borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 15.0)), + ), + child: PhotoView( + imageProvider: ImageCustomProvider.getImageProvider(appContext, i.resourceId!, i.resourceUrl!), + minScale: PhotoViewComputedScale.contained * 0.8, + maxScale: PhotoViewComputedScale.contained * 3.0, + backgroundDecoration: BoxDecoration( + color: kBackgroundGrey, + shape: BoxShape.rectangle, + borderRadius: BorderRadius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 15.0), + ), + ), + ), + ), + ); + }, + ); + } + }, + child: Container( + decoration: BoxDecoration( + //color: kBackgroundLight, + image: DecorationImage( + image: ImageCustomProvider.getImageProvider(appContext, i.resourceId!, i.resourceUrl!), + fit: BoxFit.cover, ), - ) : Center(child: Text('No data')), + borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 15.0)), + /*border: Border.all( + color: kBackgroundGrey, + width: 1.0, + ),*/ + ), ), ); break; case ResourceType.Video: case ResourceType.VideoUrl: case ResourceType.Audio: - widgetToInclude = Container( - decoration: BoxDecoration( - color: kBackgroundSecondGrey, - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 15.0), + widgetToInclude = GestureDetector( + behavior: HitTestBehavior.translucent, + onTap: () { + if(addFullScreen && i.resourceType != ResourceType.Audio) { + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 20.0)) + ), + contentPadding: EdgeInsets.zero, + // title: Text(eventAgenda.name!), + content: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 20.0)), + color: kBackgroundColor, + ), + height: size.height * 0.8, + width: size.width * 0.8, + child: Center(child: showElementForResource(ResourceDTO(id: i.resourceId, url: i.resourceUrl, type: i.resourceType), appContext, false, true)), + ), + ); + }, + ); + } + }, + child: IgnorePointer( + ignoring: i.resourceType != ResourceType.Audio, + child: Container( + decoration: BoxDecoration( + color: Colors.yellow, + shape: BoxShape.rectangle, + borderRadius: BorderRadius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 15.0), + ), + child: showElementForResource(ResourceDTO(id: i.resourceId, url: i.resourceUrl, type: i.resourceType), appContext, false, true), + ), ), - child: showElementForResource(ResourceDTO(id: i.resourceId, url: i.resourceUrl, type: i.resourceType), appContext, false, true), ); break; } return Center( child: Container( + height: MediaQuery.of(context).size.height * 0.6, + width: MediaQuery.of(context).size.width * 0.72, child: AspectRatio( aspectRatio: 16 / 9, child: ClipRect( @@ -307,4 +590,3 @@ getElementForResource(BuildContext context, AppContext appContext, ContentGeoPoi ), ); } - diff --git a/lib/Screens/Menu/menu_view.dart b/lib/Screens/Menu/menu_view.dart index 3b41893..7463b6e 100644 --- a/lib/Screens/Menu/menu_view.dart +++ b/lib/Screens/Menu/menu_view.dart @@ -12,6 +12,7 @@ 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/MainView/section_page_detail.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'; @@ -43,7 +44,7 @@ class _MenuView extends State { menuDTO = MenuDTO.fromJson(jsonDecode(widget.section.data!))!; print(menuDTO); - isImageBackground = true; //widget.isImageBackground; + isImageBackground = widget.isImageBackground; super.initState(); } @@ -58,212 +59,99 @@ class _MenuView extends State { final appContext = Provider.of(context); Size size = MediaQuery.of(context).size; TabletAppContext tabletAppContext = appContext.getContext() as TabletAppContext; + ConfigurationDTO configurationDTO = appContext.getContext().configuration; + Color backgroundColor = appContext.getContext().configuration != null ? new Color(int.parse(appContext.getContext().configuration.secondaryColor.split('(0x')[1].split(')')[0], radix: 16)) : Colors.white; + Color textColor = backgroundColor.computeLuminance() > 0.5 ? Colors.black : Colors.white; - if (selectedSection != null) { - var elementToShow; - switch (selectedSection!.type) { - case SectionType.Map : - elementToShow = ChangeNotifierProvider( - create: (_) => - MapContext(new MapMarker( - latitude: null, - longitude: null, - title: '', - description: '')), - 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,) - : CircularProgressIndicator()),*/ - ); - break; - case SectionType.Web : // WEB - elementToShow = WebView(section: selectedSection); - break; - case SectionType.Video : // Video - elementToShow = VideoView(section: selectedSection); - break; - case SectionType.Slider : // Slider - elementToShow = SliderView(section: selectedSection); - break; - case SectionType.Quizz : // Quizz - elementToShow = QuizzView(section: selectedSection); - break; - case SectionType.Pdf : // Pdf - elementToShow = PDFViewWidget(section: selectedSection); - break; - case SectionType.Puzzle : // Puzzle - elementToShow = PuzzleView(section: selectedSection); - break; - case SectionType.Agenda : // Agenda - elementToShow = AgendaView(section: selectedSection); - break; - /*case SectionType.article : // Article - elementToShow = ArticleView(section: selectedSection); - break;*/ - default: - elementToShow = Text('Section type not supported'); - break; - } - return Stack( - children: [ - Center( - child: Padding( - padding: selectedSection!.type == SectionType.Video || selectedSection!.type == SectionType.Web ? EdgeInsets.all(8.0) : EdgeInsets.all(0.0), + return Center( + child: GridView.builder( + shrinkWrap: true, + gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, childAspectRatio: kIsWeb ? 1.7 : 1.4), + itemCount: menuDTO.sections!.length, + itemBuilder: (BuildContext context, int index) { + return InkWell( + onTap: () async { + SectionDTO? section = await (appContext.getContext() as TabletAppContext).clientAPI!.sectionApi!.sectionGetDetail(menuDTO.sections![index].id!); + setState(() { + //selectedSection = section; + //selectedSection = menuDTO.sections![index]; + Navigator.push( + context, + MaterialPageRoute( + builder: (context) { + return SectionPageDetail(configurationDTO: configurationDTO, sectionDTO: section!, textColor: textColor, isImageBackground: isImageBackground, elementToShow: getContent(tabletAppContext, section, isImageBackground), isFromMenu: true); + }, + ),// For pushAndRemoveUntil + ); + }); + }, child: Container( - width: size.width, - decoration: selectedSection!.type != SectionType.Video && selectedSection!.type != SectionType.Web && selectedSection!.type != SectionType.Slider && selectedSection!.type != SectionType.Map ? BoxDecoration( - color: kBackgroundLight, - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 20.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(left: 15.0, right: 15.0), - child: elementToShow), - ), - ), - ), - Padding( - padding: const EdgeInsets.only(bottom: 5, right: 5), - child: Align( - alignment: Alignment.bottomRight, - child: InkWell( - onTap: () { - setState(() { - selectedSection = null; - }); - }, - child: Container( - decoration: BoxDecoration( - color: appContext.getContext().configuration == null ? kBackgroundGrey : appContext.getContext().configuration.secondaryColor != null ? new Color(int.parse(appContext.getContext().configuration.secondaryColor.split('(0x')[1].split(')')[0], radix: 16)): kBackgroundGrey, - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 20.0), - boxShadow: [ - BoxShadow( - color: kBackgroundSecondGrey, - spreadRadius: 0.5, - blurRadius: 5, - offset: Offset(0, 1.5), // changes position of shadow - ), - ], - ), - child: Icon( - Icons.arrow_back, - size: 95, - color: kMainGrey, - ), - ), - ) - ), - ), - ], - ); - } else { - return Center( - child: GridView.builder( - shrinkWrap: true, - gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, childAspectRatio: kIsWeb ? 1.7 : 1.4), - itemCount: menuDTO.sections!.length, - itemBuilder: (BuildContext context, int index) { - return InkWell( - onTap: () async { - SectionDTO? section = await (appContext.getContext() as TabletAppContext).clientAPI!.sectionApi!.sectionGetDetail(menuDTO.sections![index].id!); - setState(() { - selectedSection = section; - //selectedSection = menuDTO.sections![index]; - }); - }, - child: Container( - decoration: isImageBackground ? boxDecoration(appContext, menuDTO.sections![index], false) : null, - padding: const EdgeInsets.all(25), - margin: EdgeInsets.symmetric(vertical: 15, horizontal: 15), - child: isImageBackground ? Align( - alignment: Alignment.bottomRight, - child: FractionallySizedBox( - heightFactor: 0.5, - child: Column( - children: [ - Align( - alignment: Alignment.centerRight, - child: HtmlWidget( - menuDTO.sections![index].title!.firstWhere((translation) => translation.language == appContext.getContext().language).value!, - customStylesBuilder: (element) { - return {'text-align': 'right'}; - }, - textStyle: new TextStyle(fontSize: kIsWeb? kWebMenuTitleDetailSize : kMenuTitleDetailSize), - ), + decoration: isImageBackground ? boxDecoration(appContext, menuDTO.sections![index], false) : null, + padding: const EdgeInsets.all(25), + margin: EdgeInsets.symmetric(vertical: 15, horizontal: 15), + child: isImageBackground ? Align( + alignment: Alignment.bottomRight, + child: FractionallySizedBox( + heightFactor: 0.5, + child: Column( + children: [ + Align( + alignment: Alignment.centerRight, + child: HtmlWidget( + menuDTO.sections![index].title!.firstWhere((translation) => translation.language == appContext.getContext().language).value!, + customStylesBuilder: (element) { + return {'text-align': 'right'}; + }, + textStyle: new TextStyle(fontSize: kIsWeb? kWebMenuTitleDetailSize : kMenuTitleDetailSize), ), - /*Align( - alignment: Alignment.centerRight, - child: HtmlWidget( - menuDTO.sections![index].description!.firstWhere((translation) => translation.language == appContext.getContext().language).value!, - customStylesBuilder: (element) { - return {'text-align': 'right'}; - }, - textStyle: new TextStyle(fontSize: kIsWeb? kWebSectionDescriptionDetailSize: kSectionDescriptionDetailSize, fontFamily: ""), - ), - ),*/ - ], - ) - ), - ) : Column( - children: [ - Expanded( - flex: 8, - child: Container( - decoration: BoxDecoration( - color: menuDTO.sections![index].imageSource == null ? kBackgroundColor : null, // default color if no image - shape: BoxShape.rectangle, - image: menuDTO.sections![index].imageSource != null ? new DecorationImage( - fit: BoxFit.cover, - image: ImageCustomProvider.getImageProvider(appContext, menuDTO.sections![index].imageId!, menuDTO.sections![index].imageSource!), - ): null, ), - ) - ), - Expanded( - flex: 2, - child: Center( - child: HtmlWidget( - menuDTO.sections![index].title!.firstWhere((translation) => translation.language == appContext.getContext().language).value ?? "", - customStylesBuilder: (element) { - return {'text-align': 'center', 'font-family': "Roboto"}; - }, - textStyle: TextStyle(fontSize: 25),//calculateFontSize(constraints.maxWidth, constraints.maxHeight, kIsWeb ? kWebMenuTitleDetailSize : kMenuTitleDetailSize)), - ), - ) - ) - ], + /*Align( + alignment: Alignment.centerRight, + child: HtmlWidget( + menuDTO.sections![index].description!.firstWhere((translation) => translation.language == appContext.getContext().language).value!, + customStylesBuilder: (element) { + return {'text-align': 'right'}; + }, + textStyle: new TextStyle(fontSize: kIsWeb? kWebSectionDescriptionDetailSize: kSectionDescriptionDetailSize, fontFamily: ""), + ), + ),*/ + ], + ) ), + ) : Column( + children: [ + Expanded( + flex: 8, + child: Container( + decoration: BoxDecoration( + color: menuDTO.sections![index].imageSource == null ? kBackgroundColor : null, // default color if no image + shape: BoxShape.rectangle, + image: menuDTO.sections![index].imageSource != null ? new DecorationImage( + fit: BoxFit.cover, + image: ImageCustomProvider.getImageProvider(appContext, menuDTO.sections![index].imageId!, menuDTO.sections![index].imageSource!), + ): null, + ), + ) + ), + Expanded( + flex: 2, + child: Center( + child: HtmlWidget( + menuDTO.sections![index].title!.firstWhere((translation) => translation.language == appContext.getContext().language).value ?? "", + customStylesBuilder: (element) { + return {'text-align': 'center', 'font-family': "Roboto"}; + }, + textStyle: TextStyle(fontSize: 25),//calculateFontSize(constraints.maxWidth, constraints.maxHeight, kIsWeb ? kWebMenuTitleDetailSize : kMenuTitleDetailSize)), + ), + ) + ) + ], ), - ); - } - ), - ); - } + ), + ); + } + ), + ); } } diff --git a/lib/Screens/Previous/previous_view.dart b/lib/Screens/Previous/previous_view.dart index 210597e..cf09be8 100644 --- a/lib/Screens/Previous/previous_view.dart +++ b/lib/Screens/Previous/previous_view.dart @@ -265,11 +265,7 @@ class _PreviousViewWidget extends State with TickerProviderS height: size.height, child: ChangeNotifierProvider( create: (_) => - MapContext(new MapMarker( - latitude: null, - longitude: null, - title: '', - description: '')), + MapContext(null), child: MapViewWidget(section: SectionDTO(), icons: []) /*FutureBuilder( future: _url, builder: (BuildContext context, AsyncSnapshot snapshot) => snapshot.hasData diff --git a/lib/api/swagger.yaml b/lib/api/swagger.yaml index bb092f9..7a074e5 100644 --- a/lib/api/swagger.yaml +++ b/lib/api/swagger.yaml @@ -2153,6 +2153,12 @@ components: nullable: true items: $ref: '#/components/schemas/CategorieDTO' + latitude: + type: string + nullable: true + longitude: + type: string + nullable: true MapTypeApp: type: integer description: |- @@ -2247,6 +2253,12 @@ components: longitude: type: string nullable: true + imageResourceId: + type: string + nullable: true + imageUrl: + type: string + nullable: true schedules: type: array nullable: true diff --git a/manager_api/doc/CategorieDTO.md b/manager_api/doc/CategorieDTO.md index 5495085..e346999 100644 --- a/manager_api/doc/CategorieDTO.md +++ b/manager_api/doc/CategorieDTO.md @@ -8,6 +8,7 @@ import 'package:manager_api/api.dart'; ## Properties Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- +**id** | **int** | | [optional] **label** | [**List**](TranslationDTO.md) | | [optional] [default to const []] **icon** | **String** | | [optional] **iconResourceId** | **String** | | [optional] diff --git a/manager_api/doc/GeoPointDTO.md b/manager_api/doc/GeoPointDTO.md index 8657837..a3412ff 100644 --- a/manager_api/doc/GeoPointDTO.md +++ b/manager_api/doc/GeoPointDTO.md @@ -16,6 +16,8 @@ Name | Type | Description | Notes **categorieId** | **int** | | [optional] **latitude** | **String** | | [optional] **longitude** | **String** | | [optional] +**imageResourceId** | **String** | | [optional] +**imageUrl** | **String** | | [optional] **schedules** | [**List**](TranslationDTO.md) | | [optional] [default to const []] **prices** | [**List**](TranslationDTO.md) | | [optional] [default to const []] **phone** | [**List**](TranslationDTO.md) | | [optional] [default to const []] diff --git a/manager_api/doc/MapDTO.md b/manager_api/doc/MapDTO.md index f7f5f50..ffcad9b 100644 --- a/manager_api/doc/MapDTO.md +++ b/manager_api/doc/MapDTO.md @@ -16,6 +16,8 @@ Name | Type | Description | Notes **iconResourceId** | **String** | | [optional] **iconSource** | **String** | | [optional] **categories** | [**List**](CategorieDTO.md) | | [optional] [default to const []] +**latitude** | **String** | | [optional] +**longitude** | **String** | | [optional] [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/manager_api/lib/model/geo_point_dto.dart b/manager_api/lib/model/geo_point_dto.dart index fbc6d5e..a9acae5 100644 --- a/manager_api/lib/model/geo_point_dto.dart +++ b/manager_api/lib/model/geo_point_dto.dart @@ -21,6 +21,8 @@ class GeoPointDTO { this.categorieId, this.latitude, this.longitude, + this.imageResourceId, + this.imageUrl, this.schedules = const [], this.prices = const [], this.phone = const [], @@ -44,6 +46,10 @@ class GeoPointDTO { String? longitude; + String? imageResourceId; + + String? imageUrl; + List? schedules; List? prices; @@ -64,6 +70,8 @@ class GeoPointDTO { other.categorieId == categorieId && other.latitude == latitude && other.longitude == longitude && + other.imageResourceId == imageResourceId && + other.imageUrl == imageUrl && other.schedules == schedules && other.prices == prices && other.phone == phone && @@ -81,6 +89,8 @@ class GeoPointDTO { (categorieId == null ? 0 : categorieId!.hashCode) + (latitude == null ? 0 : latitude!.hashCode) + (longitude == null ? 0 : longitude!.hashCode) + + (imageResourceId == null ? 0 : imageResourceId!.hashCode) + + (imageUrl == null ? 0 : imageUrl!.hashCode) + (schedules == null ? 0 : schedules!.hashCode) + (prices == null ? 0 : prices!.hashCode) + (phone == null ? 0 : phone!.hashCode) + @@ -88,7 +98,7 @@ class GeoPointDTO { (site == null ? 0 : site!.hashCode); @override - String toString() => 'GeoPointDTO[id=$id, title=$title, description=$description, contents=$contents, categorie=$categorie, categorieId=$categorieId, latitude=$latitude, longitude=$longitude, schedules=$schedules, prices=$prices, phone=$phone, email=$email, site=$site]'; + String toString() => 'GeoPointDTO[id=$id, title=$title, description=$description, contents=$contents, categorie=$categorie, categorieId=$categorieId, latitude=$latitude, longitude=$longitude, imageResourceId=$imageResourceId, imageUrl=$imageUrl, schedules=$schedules, prices=$prices, phone=$phone, email=$email, site=$site]'; Map toJson() { final json = {}; @@ -132,6 +142,16 @@ class GeoPointDTO { } else { json[r'longitude'] = null; } + if (this.imageResourceId != null) { + json[r'imageResourceId'] = this.imageResourceId; + } else { + json[r'imageResourceId'] = null; + } + if (this.imageUrl != null) { + json[r'imageUrl'] = this.imageUrl; + } else { + json[r'imageUrl'] = null; + } if (this.schedules != null) { json[r'schedules'] = this.schedules; } else { @@ -187,6 +207,8 @@ class GeoPointDTO { categorieId: mapValueOfType(json, r'categorieId'), latitude: mapValueOfType(json, r'latitude'), longitude: mapValueOfType(json, r'longitude'), + imageResourceId: mapValueOfType(json, r'imageResourceId'), + imageUrl: mapValueOfType(json, r'imageUrl'), schedules: TranslationDTO.listFromJson(json[r'schedules']), prices: TranslationDTO.listFromJson(json[r'prices']), phone: TranslationDTO.listFromJson(json[r'phone']), diff --git a/manager_api/lib/model/map_dto.dart b/manager_api/lib/model/map_dto.dart index 5fae0e3..0f97a93 100644 --- a/manager_api/lib/model/map_dto.dart +++ b/manager_api/lib/model/map_dto.dart @@ -21,6 +21,8 @@ class MapDTO { this.iconResourceId, this.iconSource, this.categories = const [], + this.latitude, + this.longitude, }); /// @@ -45,31 +47,39 @@ class MapDTO { List? categories; + String? latitude; + + String? longitude; + @override bool operator ==(Object other) => identical(this, other) || other is MapDTO && - other.zoom == zoom && - other.mapType == mapType && - other.mapTypeMapbox == mapTypeMapbox && - other.mapProvider == mapProvider && - other.points == points && - other.iconResourceId == iconResourceId && - other.iconSource == iconSource && - other.categories == categories; + other.zoom == zoom && + other.mapType == mapType && + other.mapTypeMapbox == mapTypeMapbox && + other.mapProvider == mapProvider && + other.points == points && + other.iconResourceId == iconResourceId && + other.iconSource == iconSource && + other.categories == categories && + other.latitude == latitude && + other.longitude == longitude; @override int get hashCode => - // ignore: unnecessary_parenthesis - (zoom == null ? 0 : zoom!.hashCode) + - (mapType == null ? 0 : mapType!.hashCode) + - (mapTypeMapbox == null ? 0 : mapTypeMapbox!.hashCode) + - (mapProvider == null ? 0 : mapProvider!.hashCode) + - (points == null ? 0 : points!.hashCode) + - (iconResourceId == null ? 0 : iconResourceId!.hashCode) + - (iconSource == null ? 0 : iconSource!.hashCode) + - (categories == null ? 0 : categories!.hashCode); + // ignore: unnecessary_parenthesis + (zoom == null ? 0 : zoom!.hashCode) + + (mapType == null ? 0 : mapType!.hashCode) + + (mapTypeMapbox == null ? 0 : mapTypeMapbox!.hashCode) + + (mapProvider == null ? 0 : mapProvider!.hashCode) + + (points == null ? 0 : points!.hashCode) + + (iconResourceId == null ? 0 : iconResourceId!.hashCode) + + (iconSource == null ? 0 : iconSource!.hashCode) + + (categories == null ? 0 : categories!.hashCode) + + (latitude == null ? 0 : latitude!.hashCode) + + (longitude == null ? 0 : longitude!.hashCode); @override - String toString() => 'MapDTO[zoom=$zoom, mapType=$mapType, mapTypeMapbox=$mapTypeMapbox, mapProvider=$mapProvider, points=$points, iconResourceId=$iconResourceId, iconSource=$iconSource, categories=$categories]'; + String toString() => 'MapDTO[zoom=$zoom, mapType=$mapType, mapTypeMapbox=$mapTypeMapbox, mapProvider=$mapProvider, points=$points, iconResourceId=$iconResourceId, iconSource=$iconSource, categories=$categories, latitude=$latitude, longitude=$longitude]'; Map toJson() { final json = {}; @@ -113,6 +123,16 @@ class MapDTO { } else { json[r'categories'] = null; } + if (this.latitude != null) { + json[r'latitude'] = this.latitude; + } else { + json[r'latitude'] = null; + } + if (this.longitude != null) { + json[r'longitude'] = this.longitude; + } else { + json[r'longitude'] = null; + } return json; } @@ -143,6 +163,8 @@ class MapDTO { iconResourceId: mapValueOfType(json, r'iconResourceId'), iconSource: mapValueOfType(json, r'iconSource'), categories: CategorieDTO.listFromJson(json[r'categories']), + latitude: mapValueOfType(json, r'latitude'), + longitude: mapValueOfType(json, r'longitude'), ); } return null; diff --git a/manager_api/lib/model/section_type.dart b/manager_api/lib/model/section_type.dart index fe65f35..5a9cebe 100644 --- a/manager_api/lib/model/section_type.dart +++ b/manager_api/lib/model/section_type.dart @@ -10,7 +10,7 @@ part of openapi.api; -/// 0 = Map 1 = Slider 2 = Video 3 = Web 4 = Menu 5 = Quizz 6 = Article 7 = PDF 8 = Puzzle 9 = Agenda +/// 0 = Map 1 = Slider 2 = Video 3 = Web 4 = Menu 5 = Quizz 6 = Article 7 = PDF 8 = Puzzle 9 = Agenda 10 = Weather class SectionType { /// Instantiate a new enum with the provided [value]. const SectionType._(this.value);