diff --git a/lib/Helpers/ImageCustomProvider.dart b/lib/Helpers/ImageCustomProvider.dart new file mode 100644 index 0000000..58ac3fb --- /dev/null +++ b/lib/Helpers/ImageCustomProvider.dart @@ -0,0 +1,29 @@ +import 'dart:io'; + +import 'package:cached_network_image/cached_network_image.dart'; +import 'package:flutter/material.dart'; +import 'package:tablet_app/Models/tabletContext.dart'; +import 'package:tablet_app/app_context.dart'; + +class ImageCustomProvider { + static ImageProvider getImageProvider(AppContext appContext, String imageId, String imageSource) { + TabletAppContext tabletAppContext = appContext.getContext(); + if(appContext.getContext().localPath != null && tabletAppContext.configuration != null) { + Directory configurationDirectory = Directory('${tabletAppContext.localPath!}/${tabletAppContext.configuration!.id!}'); + List fileList = configurationDirectory.listSync(); + + print(fileList); + + if (fileList.isNotEmpty) { + File file = File(fileList.first.path); + print("FILE EXISTT"); + return FileImage(file); + } + } + + // If localpath not found or file missing + print("MISSINGG FILE"); + return CachedNetworkImageProvider(imageSource); + } +} + diff --git a/lib/Models/agenda.dart b/lib/Models/agenda.dart new file mode 100644 index 0000000..5657845 --- /dev/null +++ b/lib/Models/agenda.dart @@ -0,0 +1,124 @@ +import 'dart:convert'; + +class Agenda { + List events; + + Agenda({required this.events}); + + factory Agenda.fromJson(String jsonString) { + final List jsonList = json.decode(jsonString); + List events = []; + + for (var eventData in jsonList) { + events.add(EventAgenda.fromJson(eventData)); + } + + return Agenda(events: events); + } +} + +class EventAgenda { + String name; + String description; + String type; + DateTime dateAdded; + DateTime dateFrom; + DateTime dateTo; + String dateHour; + EventAddress address; + String website; + String phone; + String idVideoYoutube; + String email; + String image; + + EventAgenda({ + required this.name, + required this.description, + required this.type, + required this.dateAdded, + required this.dateFrom, + required this.dateTo, + required this.dateHour, + required this.address, + required this.website, + required this.phone, + required this.idVideoYoutube, + required this.email, + required this.image, + }); + + factory EventAgenda.fromJson(Map json) { + return EventAgenda( + name: json['name'], + description: json['description'], + type: json['type'], + dateAdded: DateTime.parse(json['date_added']), + dateFrom: DateTime.parse(json['date_from']), + dateTo: DateTime.parse(json['date_to']), + dateHour: json['date_hour'], + address: EventAddress.fromJson(json['address']), + website: json['website'], + phone: json['phone'], + idVideoYoutube: json['id_video_youtube'], + email: json['email'], + image: json['image'], + ); + } +} + +class EventAddress { + String address; + double lat; + double lng; + int zoom; + String placeId; + String name; + String streetNumber; + String streetName; + String streetNameShort; + String city; + String state; + String stateShort; + String postCode; + String country; + String countryShort; + + EventAddress({ + required this.address, + required this.lat, + required this.lng, + required this.zoom, + required this.placeId, + required this.name, + required this.streetNumber, + required this.streetName, + required this.streetNameShort, + required this.city, + required this.state, + required this.stateShort, + required this.postCode, + required this.country, + required this.countryShort, + }); + + factory EventAddress.fromJson(Map json) { + return EventAddress( + address: json['address'], + lat: json['lat'], + lng: json['lng'], + zoom: json['zoom'], + placeId: json['place_id'], + name: json['name'], + streetNumber: json['street_number'], + streetName: json['street_name'], + streetNameShort: json['street_name_short'], + city: json['city'], + state: json['state'], + stateShort: json['state_short'], + postCode: json['post_code'], + country: json['country'], + countryShort: json['country_short'], + ); + } +} diff --git a/lib/Screens/Agenda/agenda_view.dart b/lib/Screens/Agenda/agenda_view.dart index 5b4cfe0..66bc30c 100644 --- a/lib/Screens/Agenda/agenda_view.dart +++ b/lib/Screens/Agenda/agenda_view.dart @@ -35,7 +35,6 @@ class _AgendaView extends State { super.dispose(); } - @override Widget build(BuildContext context) { return new Center( diff --git a/lib/Screens/Configuration/config_view.dart b/lib/Screens/Configuration/config_view.dart index f4269b7..b085c60 100644 --- a/lib/Screens/Configuration/config_view.dart +++ b/lib/Screens/Configuration/config_view.dart @@ -15,6 +15,7 @@ import 'package:tablet_app/Components/loading_common.dart'; import 'package:tablet_app/Components/rounded_input_field.dart'; import 'package:tablet_app/Helpers/DatabaseHelper.dart'; import 'package:tablet_app/Helpers/DeviceInfoHelper.dart'; +import 'package:tablet_app/Helpers/ImageCustomProvider.dart'; import 'package:tablet_app/Helpers/MQTTHelper.dart'; import 'package:tablet_app/Models/tabletContext.dart'; import 'package:tablet_app/Screens/MainView/dropDown_configuration.dart'; @@ -351,29 +352,6 @@ Future getIP(bool isWLAN) async { return null; } -boxDecoration(SectionDTO section) { - return BoxDecoration( - color: kBackgroundLight, - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(30.0), - image: new DecorationImage( - fit: BoxFit.cover, - colorFilter: new ColorFilter.mode(Colors.black.withOpacity(0.5), BlendMode.dstATop), - image: CachedNetworkImageProvider(section.imageSource!), /*new NetworkImage( - section.imageSource!, - ),*/ - ), - boxShadow: [ - BoxShadow( - color: kBackgroundSecondGrey, - spreadRadius: 0.5, - blurRadius: 5, - offset: Offset(0, 1.5), // changes position of shadow - ), - ], - ); -} - Future?> getConfigurations(dynamic appContext) async { TabletAppContext tabletAppContext = (appContext.getContext() as TabletAppContext); print(tabletAppContext); diff --git a/lib/Screens/MainView/main_view.dart b/lib/Screens/MainView/main_view.dart index 16b2a0b..0c97ef8 100644 --- a/lib/Screens/MainView/main_view.dart +++ b/lib/Screens/MainView/main_view.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'dart:io'; import 'dart:math'; import 'package:cached_network_image/cached_network_image.dart'; @@ -12,6 +13,7 @@ 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/Screens/Agenda/agenda_view.dart'; import 'package:tablet_app/Screens/Article/article_view.dart'; @@ -141,9 +143,7 @@ class _MainViewWidget extends State { image: new DecorationImage( fit: BoxFit.cover, colorFilter: new ColorFilter.mode(Colors.white.withOpacity(0.8), BlendMode.lighten), - image: CachedNetworkImageProvider(configurationDTO.imageSource!),/*new NetworkImage( - configurationDTO.imageSource!, - ),*/ + image: ImageCustomProvider.getImageProvider(appContext, configurationDTO.imageId!, configurationDTO.imageSource!), ), ) : null, child: Column( @@ -160,7 +160,7 @@ class _MainViewWidget extends State { child: Container( /*width: 125, height: 125,*/ - decoration: boxDecoration(sectionSelected!, true), + decoration: boxDecoration(appContext, sectionSelected!, true), ), ), ), @@ -258,9 +258,7 @@ class _MainViewWidget extends State { image: new DecorationImage( fit: BoxFit.cover, colorFilter: new ColorFilter.mode(Colors.grey.withOpacity(0.1), BlendMode.color), - image: CachedNetworkImageProvider(configurationDTO.imageSource!),/*new NetworkImage( - configurationDTO.imageSource!, - ),*/ + image: ImageCustomProvider.getImageProvider(appContext, configurationDTO.imageId!, configurationDTO.imageSource!) ), ) : null, child: Stack( @@ -282,12 +280,10 @@ class _MainViewWidget extends State { 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/yy').format(value), style: TextStyle(fontSize: 15, color: textColor)), + 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/yy').format(value), style: TextStyle(fontSize: 15, color: textColor)), - if(configurationDTO.weatherCity != null) // TODO Weather - Text('TODO - ' + configurationDTO.weatherCity!, style: TextStyle(fontSize: 15, color: textColor)) + Text(DateFormat('dd/MM').format(value), style: TextStyle(fontSize: 15, color: textColor)), ], ), ) @@ -321,7 +317,7 @@ class _MainViewWidget extends State { }); }, child: Container( - decoration: boxDecoration(snapshot.data[index], false), + decoration: boxDecoration(appContext, snapshot.data[index], false), padding: const EdgeInsets.all(25), margin: EdgeInsets.symmetric(vertical: 25, horizontal: 25), child: Align( @@ -418,6 +414,14 @@ class _MainViewWidget extends State { ), ), ), + if(configurationDTO.weatherCity != null) + Positioned( + bottom: 0, + left: 0, + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Text('Weather - ' + configurationDTO.weatherCity!, style: TextStyle(fontSize: 15, color: textColor)) + )) ]), ), floatingActionButton: InkWell( @@ -524,7 +528,7 @@ double calculateFontSize(double parentWidth, double parentHeight, double baseSiz return calculatedFontSize < baseSize ? calculatedFontSize : baseSize; } -boxDecoration(SectionDTO section, bool isSelected) { +boxDecoration(AppContext appContext, SectionDTO section, bool isSelected) { return BoxDecoration( color: kBackgroundLight, shape: BoxShape.rectangle, @@ -532,9 +536,7 @@ boxDecoration(SectionDTO section, bool isSelected) { image: section.imageSource != null ? new DecorationImage( fit: !isSelected || kIsWeb ? BoxFit.cover : BoxFit.contain, colorFilter: !isSelected? new ColorFilter.mode(Colors.black.withOpacity(kIsWeb ? 0.3 : 0.3), BlendMode.dstATop) : null, - image: CachedNetworkImageProvider(section.imageSource!),/*new NetworkImage( - section.imageSource!, - ),*/ + image: ImageCustomProvider.getImageProvider(appContext, section.imageId!, section.imageSource!), ): null, boxShadow: [ BoxShadow( diff --git a/lib/Screens/Map/marker_view.dart b/lib/Screens/Map/marker_view.dart index eae3fa5..8a376de 100644 --- a/lib/Screens/Map/marker_view.dart +++ b/lib/Screens/Map/marker_view.dart @@ -7,6 +7,7 @@ import 'package:manager_api/api.dart'; import 'package:photo_view/photo_view.dart'; import 'package:provider/provider.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/Screens/Quizz/quizz_view.dart'; import 'package:tablet_app/app_context.dart'; @@ -265,9 +266,7 @@ getElementForResource(BuildContext context, AppContext appContext, ContentGeoPoi aspectRatio: 16 / 9, child: ClipRect( child: i.resourceUrl != null ? PhotoView( - imageProvider: CachedNetworkImageProvider(i.resourceUrl!), /*new NetworkImage( - i.imageSource, - ),*/ + imageProvider: ImageCustomProvider.getImageProvider(appContext, i.resourceId!, i.resourceUrl!), minScale: PhotoViewComputedScale.contained * 0.8, maxScale: PhotoViewComputedScale.contained * 3.0, backgroundDecoration: BoxDecoration( diff --git a/lib/Screens/Menu/menu_view.dart b/lib/Screens/Menu/menu_view.dart index 1bf7781..cb68ef6 100644 --- a/lib/Screens/Menu/menu_view.dart +++ b/lib/Screens/Menu/menu_view.dart @@ -6,6 +6,7 @@ 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/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'; @@ -171,7 +172,7 @@ class _MenuView extends State { }); }, child: Container( - decoration: boxDecoration(menuDTO.sections![index], false), + decoration: boxDecoration(appContext, menuDTO.sections![index], false), padding: const EdgeInsets.all(25), margin: EdgeInsets.symmetric(vertical: kIsWeb ? 15 : 25, horizontal: kIsWeb ? 15 : 25), child: Align( @@ -213,7 +214,7 @@ class _MenuView extends State { } } -boxDecoration(SectionDTO section, bool isSelected) { +boxDecoration(AppContext appContext, SectionDTO section, bool isSelected) { return BoxDecoration( color: kBackgroundLight, shape: BoxShape.rectangle, @@ -221,9 +222,7 @@ boxDecoration(SectionDTO section, bool isSelected) { image: section.imageSource != null ? new DecorationImage( fit: kIsWeb ? BoxFit.cover : BoxFit.contain, colorFilter: !isSelected? new ColorFilter.mode(Colors.black.withOpacity(0.3), BlendMode.dstATop) : null, - image: CachedNetworkImageProvider(section.imageSource!), /*new NetworkImage( - section.imageSource!, - ),*/ + image: ImageCustomProvider.getImageProvider(appContext, section.imageId!, section.imageSource!), ): null, boxShadow: [ BoxShadow( diff --git a/lib/Screens/PDF/pdf_view.dart b/lib/Screens/PDF/pdf_view.dart index fcbc3b3..7e68715 100644 --- a/lib/Screens/PDF/pdf_view.dart +++ b/lib/Screens/PDF/pdf_view.dart @@ -9,7 +9,10 @@ import 'package:flutter/material.dart'; import 'package:flutter_pdfview/flutter_pdfview.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_common.dart'; +import 'package:tablet_app/Models/tabletContext.dart'; +import 'package:tablet_app/app_context.dart'; class PDFViewWidget extends StatefulWidget { @@ -46,26 +49,34 @@ class _PDFViewWidget extends State { });*/ } - Future createFileOfPdfUrl(String source_) async { + Future createFileOfPdfUrl(TabletAppContext tabletAppContext, PdfDTO pdfDTO) async { Completer completer = Completer(); - print("Start download file from internet!"); - try { - // "https://berlin2017.droidcon.cod.newthinking.net/sites/global.droidcon.cod.newthinking.net/files/media/documents/Flutter%20-%2060FPS%20UI%20of%20the%20future%20%20-%20DroidconDE%2017.pdf"; - // final url = "https://pdfkit.org/docs/guide.pdf"; - final url = source_; - final filename = url.substring(url.lastIndexOf("/") + 1); - var request = await HttpClient().getUrl(Uri.parse(url)); - var response = await request.close(); - var bytes = await consolidateHttpClientResponseBytes(response); - var dir = await getApplicationDocumentsDirectory(); - print("Download files"); - print("${dir.path}/$filename"); - File file = File("${dir.path}/$filename"); - await file.writeAsBytes(bytes, flush: true); + var file = await _checkIfLocalResourceExists(tabletAppContext, pdfDTO.resourceId!); + + if(file == null) { + print("Start download file from internet!"); + try { + // "https://berlin2017.droidcon.cod.newthinking.net/sites/global.droidcon.cod.newthinking.net/files/media/documents/Flutter%20-%2060FPS%20UI%20of%20the%20future%20%20-%20DroidconDE%2017.pdf"; + // final url = "https://pdfkit.org/docs/guide.pdf"; + final url = pdfDTO.resourceUrl!; + final filename = url.substring(url.lastIndexOf("/") + 1); + var request = await HttpClient().getUrl(Uri.parse(url)); + var response = await request.close(); + var bytes = await consolidateHttpClientResponseBytes(response); + var dir = await getApplicationDocumentsDirectory(); + print("Download files"); + print("${dir.path}/$filename"); + File file = File("${dir.path}/$filename"); + + await file.writeAsBytes(bytes, flush: true); + completer.complete(file); + } catch (e) { + throw Exception('Error parsing asset file!'); + } + } else { + print("FOUND FILE PDF"); completer.complete(file); - } catch (e) { - throw Exception('Error parsing asset file!'); } return completer.future; @@ -77,74 +88,92 @@ class _PDFViewWidget extends State { super.dispose(); } - @override - Widget build(BuildContext context) => pdfDTO.resourceUrl != null && pdfDTO.resourceUrl!.length > 0 ? - Padding( - padding: const EdgeInsets.all(12.5), - child: FutureBuilder( - future: createFileOfPdfUrl(pdfDTO.resourceUrl!), - builder: (context, AsyncSnapshot snapshot) { - print("snapshot.data"); - print(snapshot.data); - if (snapshot.connectionState == ConnectionState.done) { - return Stack( - children: [ - PDFView( - filePath: snapshot.data.path, - enableSwipe: true, - swipeHorizontal: true, - autoSpacing: true, - pageFling: true, - fitPolicy: FitPolicy.HEIGHT, - onRender: (_pages) { - //setState(() { - pages = _pages; - isReady = true; - //}); - }, - onError: (error) { - print(error.toString()); - }, - onPageError: (page, error) { - print('$page: ${error.toString()}'); - }, - onViewCreated: (PDFViewController pdfViewController) { - //_controller.complete(pdfViewController); - }, - onPageChanged: (int? page, int? total) { - currentPage = page; - pages = total; - currentState.value = {'page': page!, 'total': total!}; + Widget build(BuildContext context) { + final appContext = Provider.of(context); + TabletAppContext tabletAppContext = appContext.getContext(); - print('page change: $page/$total'); - }, - ), - Positioned( - bottom: 20, - right: 20, - child: ValueListenableBuilder>( - valueListenable: currentState, - builder: (context, value, _) { - return Container( - //color: Colors.blueAccent, - child: Text("${value["page"]!+1}/${value["total"]!}", - style: TextStyle(color: Colors.black, fontSize: 30)) - ); + return pdfDTO.resourceUrl != null && pdfDTO.resourceUrl!.length > 0 ? + Padding( + padding: const EdgeInsets.all(12.5), + child: FutureBuilder( + future: createFileOfPdfUrl(tabletAppContext, pdfDTO), + builder: (context, AsyncSnapshot snapshot) { + print("snapshot.data"); + print(snapshot.data); + if (snapshot.connectionState == ConnectionState.done) { + return Stack( + children: [ + PDFView( + filePath: snapshot.data.path, + enableSwipe: true, + swipeHorizontal: true, + autoSpacing: true, + pageFling: true, + fitPolicy: FitPolicy.HEIGHT, + onRender: (_pages) { + //setState(() { + pages = _pages; + isReady = true; + //}); + }, + onError: (error) { + print(error.toString()); + }, + onPageError: (page, error) { + print('$page: ${error.toString()}'); + }, + onViewCreated: (PDFViewController pdfViewController) { + //_controller.complete(pdfViewController); + }, + onPageChanged: (int? page, int? total) { + currentPage = page; + pages = total; + currentState.value = {'page': page!, 'total': total!}; + + print('page change: $page/$total'); }, ), - ), - ], - ); - } else { - return Center( - child: Container( - child: LoadingCommon() - ) - ); - } - } - ), - ) : - Center(child: Text("Le PDF ne peut pas être affiché, il n'existe pas")); -} //_webView \ No newline at end of file + Positioned( + bottom: 20, + right: 20, + child: ValueListenableBuilder>( + valueListenable: currentState, + builder: (context, value, _) { + return Container( + //color: Colors.blueAccent, + child: Text("${value["page"]!+1}/${value["total"]!}", + style: TextStyle(color: Colors.black, fontSize: 30)) + ); + }, + ), + ), + ], + ); + } else { + return Center( + child: Container( + child: LoadingCommon() + ) + ); + } + } + ), + ) : + Center(child: Text("Le PDF ne peut pas être affiché, il n'existe pas")); + } +} //_webView + +Future _checkIfLocalResourceExists(TabletAppContext tabletAppContext, String resourceId) async { + Directory? appDocumentsDirectory = 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(resourceId))) { + File file = File(fileList.firstWhere((fileL) => fileL.uri.pathSegments.last.contains(resourceId)).path); + return file; + } + + return null; +} \ No newline at end of file diff --git a/lib/Screens/Quizz/quizz_view.dart b/lib/Screens/Quizz/quizz_view.dart index 8ee1843..e54ec32 100644 --- a/lib/Screens/Quizz/quizz_view.dart +++ b/lib/Screens/Quizz/quizz_view.dart @@ -11,6 +11,7 @@ import 'package:manager_api/api.dart'; import 'package:provider/provider.dart'; import 'package:tablet_app/Components/Buttons/rounded_button.dart'; import 'package:tablet_app/Components/show_element_for_resource.dart'; +import 'package:tablet_app/Helpers/ImageCustomProvider.dart'; import 'package:tablet_app/Models/ResponseSubDTO.dart'; import 'package:tablet_app/Screens/Quizz/showResponses.dart'; import 'package:tablet_app/Screens/Slider/slider_view.dart'; @@ -282,9 +283,7 @@ class _QuizzView extends State { image: i.resourceUrl != null ? new DecorationImage( fit: BoxFit.cover, opacity: 0.35, - image: CachedNetworkImageProvider(i.resourceUrl!),/* new NetworkImage( - i.resourceUrl!, - ),*/ + image: ImageCustomProvider.getImageProvider(appContext, i.resourceId!, i.resourceUrl!) ): null, boxShadow: [ BoxShadow( @@ -532,10 +531,8 @@ getElementForResource(BuildContext context, AppContext appContext, TranslationAn decoration: BoxDecoration( color: const Color(0xff7c94b6), image: DecorationImage( - image: CachedNetworkImageProvider(i.resourceUrl!),/*new NetworkImage( - levelToShow.source_, - ),*/ - fit: BoxFit.cover, + image: ImageCustomProvider.getImageProvider(appContext, i.resourceId!, i.resourceUrl!), + fit: BoxFit.cover, ), borderRadius: BorderRadius.all(Radius.circular(15.0)), border: Border.all( diff --git a/lib/Screens/Quizz/showResponses.dart b/lib/Screens/Quizz/showResponses.dart index 9988c5c..90f08ae 100644 --- a/lib/Screens/Quizz/showResponses.dart +++ b/lib/Screens/Quizz/showResponses.dart @@ -8,6 +8,7 @@ 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/Helpers/ImageCustomProvider.dart'; import 'package:tablet_app/Models/ResponseSubDTO.dart'; import 'package:tablet_app/app_context.dart'; import 'package:tablet_app/constants.dart'; @@ -80,9 +81,7 @@ class _ShowReponsesWidget extends State { image: i.resourceUrl != null ? new DecorationImage( fit: BoxFit.contain, opacity: 0.35, - image: CachedNetworkImageProvider(i.resourceUrl!),/*new NetworkImage( - i.resourceUrl!, - ),*/ + image: ImageCustomProvider.getImageProvider(appContext, i.resourceId!, i.resourceUrl!), ): null, boxShadow: [ BoxShadow( diff --git a/lib/Screens/Slider/slider_view.dart b/lib/Screens/Slider/slider_view.dart index 29bdab1..c7a9fe2 100644 --- a/lib/Screens/Slider/slider_view.dart +++ b/lib/Screens/Slider/slider_view.dart @@ -11,6 +11,7 @@ import 'package:path_provider/path_provider.dart'; import 'package:provider/provider.dart'; import 'package:tablet_app/Components/show_element_for_resource.dart'; import 'package:tablet_app/Components/video_viewer.dart'; +import 'package:tablet_app/Helpers/ImageCustomProvider.dart'; import 'package:tablet_app/Models/tabletContext.dart'; import 'package:tablet_app/app_context.dart'; import 'package:tablet_app/constants.dart'; @@ -254,20 +255,8 @@ class _SliderView extends State { switch(i.resourceType) { case ResourceType.Image: - TabletAppContext tabletAppContext = appContext.getContext(); - Directory configurationDirectory = Directory('${tabletAppContext.localPath}/${tabletAppContext.configuration!.id}'); - List fileList = configurationDirectory.listSync(); - - var imageProvider = null; - if(fileList.any((fileL) => fileL.uri.pathSegments.last.contains(i.resourceId!))) { - File file = File(fileList.firstWhere((fileL) => fileL.uri.pathSegments.last.contains(i.resourceId!)).path); - imageProvider = FileImage(file); - } else { - imageProvider = new CachedNetworkImageProvider(i.resourceUrl!,); - } - widgetToInclude = PhotoView( - imageProvider: imageProvider, + imageProvider: ImageCustomProvider.getImageProvider(appContext, i.resourceId!, i.resourceUrl!), minScale: PhotoViewComputedScale.contained * 0.8, maxScale: PhotoViewComputedScale.contained * 3.0, backgroundDecoration: BoxDecoration( @@ -279,9 +268,7 @@ class _SliderView extends State { break; case ResourceType.ImageUrl: widgetToInclude = PhotoView( - imageProvider: CachedNetworkImageProvider(i.resourceUrl!),/*new NetworkImage( - i.resourceUrl!, - ),*/ + imageProvider: CachedNetworkImageProvider(i.resourceUrl!), minScale: PhotoViewComputedScale.contained * 0.8, maxScale: PhotoViewComputedScale.contained * 3.0, backgroundDecoration: BoxDecoration( diff --git a/lib/Services/downloadService.dart b/lib/Services/downloadService.dart index ebaf23b..f0fd2af 100644 --- a/lib/Services/downloadService.dart +++ b/lib/Services/downloadService.dart @@ -113,7 +113,7 @@ class _DownloadConfigurationWidgetState extends State**](SectionDTO.md) | | [optional] [default to const []] diff --git a/manager_api/lib/model/configuration_dto.dart b/manager_api/lib/model/configuration_dto.dart index 074ab24..810ef02 100644 --- a/manager_api/lib/model/configuration_dto.dart +++ b/manager_api/lib/model/configuration_dto.dart @@ -30,6 +30,9 @@ class ConfigurationDTO { this.loaderImageId, this.loaderImageUrl, this.weatherCity, + this.weatherUpdatedDate, + this.weatherResult, + this.isWeather, this.isDate, this.isHour, }); @@ -92,6 +95,18 @@ class ConfigurationDTO { String? weatherCity; + DateTime? weatherUpdatedDate; + + String? weatherResult; + + /// + /// Please note: This property should have been non-nullable! Since the specification file + /// does not include a default value (using the "default:" property), however, the generated + /// source code must fall back to having a nullable type. + /// Consider adding a "default:" property in the specification file to hide this note. + /// + bool? isWeather; + /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -127,6 +142,9 @@ class ConfigurationDTO { other.loaderImageId == loaderImageId && other.loaderImageUrl == loaderImageUrl && other.weatherCity == weatherCity && + other.weatherUpdatedDate == weatherUpdatedDate && + other.weatherResult == weatherResult && + other.isWeather == isWeather && other.isDate == isDate && other.isHour == isHour; @@ -150,11 +168,14 @@ class ConfigurationDTO { (loaderImageId == null ? 0 : loaderImageId!.hashCode) + (loaderImageUrl == null ? 0 : loaderImageUrl!.hashCode) + (weatherCity == null ? 0 : weatherCity!.hashCode) + + (weatherUpdatedDate == null ? 0 : weatherUpdatedDate!.hashCode) + + (weatherResult == null ? 0 : weatherResult!.hashCode) + + (isWeather == null ? 0 : isWeather!.hashCode) + (isDate == null ? 0 : isDate!.hashCode) + (isHour == null ? 0 : isHour!.hashCode); @override - String toString() => 'ConfigurationDTO[id=$id, label=$label, title=$title, imageId=$imageId, imageSource=$imageSource, primaryColor=$primaryColor, secondaryColor=$secondaryColor, languages=$languages, dateCreation=$dateCreation, isMobile=$isMobile, isTablet=$isTablet, isOffline=$isOffline, instanceId=$instanceId, sectionIds=$sectionIds, loaderImageId=$loaderImageId, loaderImageUrl=$loaderImageUrl, weatherCity=$weatherCity, isDate=$isDate, isHour=$isHour]'; + String toString() => 'ConfigurationDTO[id=$id, label=$label, title=$title, imageId=$imageId, imageSource=$imageSource, primaryColor=$primaryColor, secondaryColor=$secondaryColor, languages=$languages, dateCreation=$dateCreation, isMobile=$isMobile, isTablet=$isTablet, isOffline=$isOffline, instanceId=$instanceId, sectionIds=$sectionIds, loaderImageId=$loaderImageId, loaderImageUrl=$loaderImageUrl, weatherCity=$weatherCity, weatherUpdatedDate=$weatherUpdatedDate, weatherResult=$weatherResult, isWeather=$isWeather, isDate=$isDate, isHour=$isHour]'; Map toJson() { final json = {}; @@ -243,6 +264,21 @@ class ConfigurationDTO { } else { json[r'weatherCity'] = null; } + if (this.weatherUpdatedDate != null) { + json[r'weatherUpdatedDate'] = this.weatherUpdatedDate!.toUtc().toIso8601String(); + } else { + json[r'weatherUpdatedDate'] = null; + } + if (this.weatherResult != null) { + json[r'weatherResult'] = this.weatherResult; + } else { + json[r'weatherResult'] = null; + } + if (this.isWeather != null) { + json[r'isWeather'] = this.isWeather; + } else { + json[r'isWeather'] = null; + } if (this.isDate != null) { json[r'isDate'] = this.isDate; } else { @@ -296,6 +332,9 @@ class ConfigurationDTO { loaderImageId: mapValueOfType(json, r'loaderImageId'), loaderImageUrl: mapValueOfType(json, r'loaderImageUrl'), weatherCity: mapValueOfType(json, r'weatherCity'), + weatherUpdatedDate: mapDateTime(json, r'weatherUpdatedDate', ''), + weatherResult: mapValueOfType(json, r'weatherResult'), + isWeather: mapValueOfType(json, r'isWeather'), isDate: mapValueOfType(json, r'isDate'), isHour: mapValueOfType(json, r'isHour'), ); diff --git a/manager_api/lib/model/export_configuration_dto.dart b/manager_api/lib/model/export_configuration_dto.dart index 4efa6a3..34ffbc1 100644 --- a/manager_api/lib/model/export_configuration_dto.dart +++ b/manager_api/lib/model/export_configuration_dto.dart @@ -30,6 +30,9 @@ class ExportConfigurationDTO { this.loaderImageId, this.loaderImageUrl, this.weatherCity, + this.weatherUpdatedDate, + this.weatherResult, + this.isWeather, this.isDate, this.isHour, this.sections = const [], @@ -94,6 +97,18 @@ class ExportConfigurationDTO { String? weatherCity; + DateTime? weatherUpdatedDate; + + String? weatherResult; + + /// + /// Please note: This property should have been non-nullable! Since the specification file + /// does not include a default value (using the "default:" property), however, the generated + /// source code must fall back to having a nullable type. + /// Consider adding a "default:" property in the specification file to hide this note. + /// + bool? isWeather; + /// /// Please note: This property should have been non-nullable! Since the specification file /// does not include a default value (using the "default:" property), however, the generated @@ -133,6 +148,9 @@ class ExportConfigurationDTO { other.loaderImageId == loaderImageId && other.loaderImageUrl == loaderImageUrl && other.weatherCity == weatherCity && + other.weatherUpdatedDate == weatherUpdatedDate && + other.weatherResult == weatherResult && + other.isWeather == isWeather && other.isDate == isDate && other.isHour == isHour && other.sections == sections && @@ -158,13 +176,16 @@ class ExportConfigurationDTO { (loaderImageId == null ? 0 : loaderImageId!.hashCode) + (loaderImageUrl == null ? 0 : loaderImageUrl!.hashCode) + (weatherCity == null ? 0 : weatherCity!.hashCode) + + (weatherUpdatedDate == null ? 0 : weatherUpdatedDate!.hashCode) + + (weatherResult == null ? 0 : weatherResult!.hashCode) + + (isWeather == null ? 0 : isWeather!.hashCode) + (isDate == null ? 0 : isDate!.hashCode) + (isHour == null ? 0 : isHour!.hashCode) + (sections == null ? 0 : sections!.hashCode) + (resources == null ? 0 : resources!.hashCode); @override - String toString() => 'ExportConfigurationDTO[id=$id, label=$label, title=$title, imageId=$imageId, imageSource=$imageSource, primaryColor=$primaryColor, secondaryColor=$secondaryColor, languages=$languages, dateCreation=$dateCreation, isMobile=$isMobile, isTablet=$isTablet, isOffline=$isOffline, instanceId=$instanceId, sectionIds=$sectionIds, loaderImageId=$loaderImageId, loaderImageUrl=$loaderImageUrl, weatherCity=$weatherCity, isDate=$isDate, isHour=$isHour, sections=$sections, resources=$resources]'; + String toString() => 'ExportConfigurationDTO[id=$id, label=$label, title=$title, imageId=$imageId, imageSource=$imageSource, primaryColor=$primaryColor, secondaryColor=$secondaryColor, languages=$languages, dateCreation=$dateCreation, isMobile=$isMobile, isTablet=$isTablet, isOffline=$isOffline, instanceId=$instanceId, sectionIds=$sectionIds, loaderImageId=$loaderImageId, loaderImageUrl=$loaderImageUrl, weatherCity=$weatherCity, weatherUpdatedDate=$weatherUpdatedDate, weatherResult=$weatherResult, isWeather=$isWeather, isDate=$isDate, isHour=$isHour, sections=$sections, resources=$resources]'; Map toJson() { final json = {}; @@ -253,6 +274,21 @@ class ExportConfigurationDTO { } else { json[r'weatherCity'] = null; } + if (this.weatherUpdatedDate != null) { + json[r'weatherUpdatedDate'] = this.weatherUpdatedDate!.toUtc().toIso8601String(); + } else { + json[r'weatherUpdatedDate'] = null; + } + if (this.weatherResult != null) { + json[r'weatherResult'] = this.weatherResult; + } else { + json[r'weatherResult'] = null; + } + if (this.isWeather != null) { + json[r'isWeather'] = this.isWeather; + } else { + json[r'isWeather'] = null; + } if (this.isDate != null) { json[r'isDate'] = this.isDate; } else { @@ -316,6 +352,9 @@ class ExportConfigurationDTO { loaderImageId: mapValueOfType(json, r'loaderImageId'), loaderImageUrl: mapValueOfType(json, r'loaderImageUrl'), weatherCity: mapValueOfType(json, r'weatherCity'), + weatherUpdatedDate: mapDateTime(json, r'weatherUpdatedDate', ''), + weatherResult: mapValueOfType(json, r'weatherResult'), + isWeather: mapValueOfType(json, r'isWeather'), isDate: mapValueOfType(json, r'isDate'), isHour: mapValueOfType(json, r'isHour'), sections: SectionDTO.listFromJson(json[r'sections']), diff --git a/manager_api/lib/model/resource_type.dart b/manager_api/lib/model/resource_type.dart index 8cc1f79..cfde41e 100644 --- a/manager_api/lib/model/resource_type.dart +++ b/manager_api/lib/model/resource_type.dart @@ -10,7 +10,7 @@ part of openapi.api; -/// 0 = Image 1 = Video 2 = ImageUrl 3 = VideoUrl 4 = Audio 5 = PDF 6 = JSON +/// 0 = Image 1 = Video 2 = ImageUrl 3 = VideoUrl 4 = Audio 5 = PDF 6 = JSON 7 = JSONUrl class ResourceType { /// Instantiate a new enum with the provided [value]. const ResourceType._(this.value); @@ -30,6 +30,7 @@ class ResourceType { static const Audio = ResourceType._(4); static const Pdf = ResourceType._(5); static const Json = ResourceType._(6); + static const JsonUrl = ResourceType._(7); /// List of all possible values in this [enum][ResourceType]. static const values = [ @@ -39,7 +40,8 @@ class ResourceType { VideoUrl, Audio, Pdf, - Json + Json, + JsonUrl ]; static ResourceType? fromJson(dynamic value) => ResourceTypeTypeTransformer().decode(value); @@ -86,6 +88,7 @@ class ResourceTypeTypeTransformer { case "Audio": return ResourceType.Audio; case "PDF": return ResourceType.Pdf; case "JSON": return ResourceType.Json; + case "JSONUrl": return ResourceType.JsonUrl; default: if (!allowNull) { throw ArgumentError('Unknown enum value to decode: $data'); @@ -101,6 +104,7 @@ class ResourceTypeTypeTransformer { case 4: return ResourceType.Audio; case 5: return ResourceType.Pdf; case 6: return ResourceType.Json; + case 7: return ResourceType.JsonUrl; default: if (!allowNull) { throw ArgumentError('Unknown enum value to decode: $data');