diff --git a/lib/Components/audio_player.dart b/lib/Components/audio_player.dart index 1dcb434..61d97ef 100644 --- a/lib/Components/audio_player.dart +++ b/lib/Components/audio_player.dart @@ -30,6 +30,7 @@ class _AudioPlayerFloatingContainerState extends State snapshot) { @@ -94,7 +94,7 @@ showElementForResource(ResourceDTO resourceDTO, AppContext appContext) { if(resourceDTO.url == null) { return Center(child: Text("Error loading video")); } else { - return VideoViewerYoutube(videoUrl: resourceDTO.url!); + return VideoViewerYoutube(videoUrl: resourceDTO.url!, isAuto: isAuto, webView: webView); } } } diff --git a/lib/Components/video_viewer_youtube.dart b/lib/Components/video_viewer_youtube.dart index a4a1805..1eb8ea5 100644 --- a/lib/Components/video_viewer_youtube.dart +++ b/lib/Components/video_viewer_youtube.dart @@ -9,7 +9,9 @@ import 'package:youtube_player_flutter/youtube_player_flutter.dart'; class VideoViewerYoutube extends StatefulWidget { final String videoUrl; - VideoViewerYoutube({required this.videoUrl}); + final bool isAuto; + final bool webView; + VideoViewerYoutube({required this.videoUrl, required this.isAuto, this.webView = false}); @override _VideoViewerYoutube createState() => _VideoViewerYoutube(); @@ -25,7 +27,7 @@ class _VideoViewerYoutube extends State { if (widget.videoUrl.length > 0 ) { videoId = YoutubePlayer.convertUrlToId(widget.videoUrl); - if (kIsWeb) { + if (widget.webView) { final _controllerWeb = iframe.YoutubePlayerController( params: iframe.YoutubePlayerParams( mute: false, @@ -52,11 +54,12 @@ class _VideoViewerYoutube extends State { ),*/ ); } else { + // Cause memory issue on tablet videoId = YoutubePlayer.convertUrlToId(widget.videoUrl); YoutubePlayerController _controller = YoutubePlayerController( initialVideoId: videoId!, flags: YoutubePlayerFlags( - autoPlay: true, + autoPlay: widget.isAuto, controlsVisibleAtStart: false, loop: true, hideControls: false, @@ -81,13 +84,13 @@ class _VideoViewerYoutube extends State { @override void dispose() { - _videoView = null; + //_videoView = null; _videoViewWeb = null; super.dispose(); } @override Widget build(BuildContext context) => widget.videoUrl.length > 0 ? - (kIsWeb ? _videoViewWeb! : _videoView!): + (widget.webView ? _videoViewWeb! : _videoView!): Center(child: Text("La vidéo ne peut pas être affichée, l'url est incorrecte", style: new TextStyle(fontSize: kNoneInfoOrIncorrect))); } \ No newline at end of file diff --git a/lib/Screens/MainView/main_view.dart b/lib/Screens/MainView/main_view.dart index af5f345..3e617db 100644 --- a/lib/Screens/MainView/main_view.dart +++ b/lib/Screens/MainView/main_view.dart @@ -1,3 +1,4 @@ +import 'dart:async'; import 'dart:math'; import 'package:flutter/foundation.dart'; @@ -26,6 +27,7 @@ import 'package:tablet_app/Screens/Video/video_view.dart'; import 'package:tablet_app/Screens/Web/web_view.dart'; import 'package:tablet_app/app_context.dart'; import 'package:tablet_app/constants.dart'; +import 'package:intl/intl.dart'; import '../Quizz/quizz_view.dart'; import 'language_selection.dart'; @@ -41,15 +43,38 @@ class _MainViewWidget extends State { Size sizeScreen = new Size(1080.0, 1920.0); // Tablet resolution SectionDTO? sectionSelected; late ConfigurationDTO configurationDTO; - + ValueNotifier currentHourDate = ValueNotifier(DateTime.now()); + late Color backgroundColor; int rowCount = 4; + @override + void initState() { + final appContext = Provider.of(context, listen: false); + configurationDTO = appContext.getContext().configuration; + if(configurationDTO.isHour != null && configurationDTO.isHour!) { + Timer.periodic(Duration(seconds: 1), (Timer t) => _getTime(currentHourDate)); + } + super.initState(); + } + + void _getTime(ValueNotifier valueNotifier) { + //final DateTime now = DateTime.now(); + //final String formattedDateTime = _formatDateTime(now); + + //setState(() { + //_timeString = formattedDateTime; + valueNotifier.value = DateTime.now(); + //}); + } + @override Widget build(BuildContext context) { final appContext = Provider.of(context); SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: []); Size size = MediaQuery.of(context).size; - configurationDTO = appContext.getContext().configuration; + + 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; // TODO REMOVE /*if (!MQTTHelper.instance.isInstantiated) @@ -151,7 +176,7 @@ class _MainViewWidget extends State { alignment: Alignment.centerLeft, child: HtmlWidget( sectionSelected!.title!.firstWhere((translation) => translation.language == appContext.getContext().language).value!, - textStyle: new TextStyle(fontSize: kIsWeb ? kWebSectionTitleDetailSize : kSectionTitleDetailSize, color: Colors.white), + textStyle: new TextStyle(fontSize: kIsWeb ? kWebSectionTitleDetailSize : kSectionTitleDetailSize, color: textColor), ) ) ), @@ -161,7 +186,7 @@ class _MainViewWidget extends State { alignment: Alignment.centerLeft, child: HtmlWidget( sectionSelected!.description!.firstWhere((translation) => translation.language == appContext.getContext().language).value!, - textStyle: new TextStyle(fontSize: kIsWeb? kWebSectionDescriptionDetailSize : kSectionDescriptionDetailSize), + textStyle: new TextStyle(fontSize: kIsWeb? kWebSectionDescriptionDetailSize : kSectionDescriptionDetailSize, color: textColor), ) ) ) @@ -226,7 +251,7 @@ class _MainViewWidget extends State { body: Container( height: size.height, width: size.width, - color: configurationDTO.imageId == null ? configurationDTO.secondaryColor != null ? new Color(int.parse(appContext.getContext().configuration.secondaryColor.split('(0x')[1].split(')')[0], radix: 16)): kBackgroundGrey : null, + color: configurationDTO.imageId == null ? configurationDTO.secondaryColor != null ? backgroundColor : kBackgroundGrey : null, decoration: configurationDTO.imageId != null ? BoxDecoration( image: new DecorationImage( fit: BoxFit.cover, @@ -238,6 +263,35 @@ class _MainViewWidget extends State { ) : 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/yy').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)) + ], + ), + ) + ); + }, + ), LanguageSelection(size: size), Center( child: Container( @@ -271,35 +325,43 @@ class _MainViewWidget extends State { child: Align( alignment: Alignment.bottomRight, child: FractionallySizedBox( - heightFactor: 0.35, + heightFactor: 0.4, child: Container( - color: Colors.green, + //color: Colors.green, child: Column( children: [ Container( - color: Colors.blue, - child: LayoutBuilder( - builder: (BuildContext context, BoxConstraints constraints) { - return SizedBox( - width: double.infinity, - child: FittedBox( - fit: BoxFit.fitWidth, - child: Align( - alignment: Alignment.centerRight, - child: HtmlWidget( - snapshot.data[index].title.firstWhere((translation) => translation.language == appContext.getContext().language).value, - customStylesBuilder: (element) { - return {'text-align': 'right'}; - }, - textStyle: TextStyle(fontSize: calculateFontSize(constraints.maxWidth, constraints.maxHeight, kIsWeb ? kWebMenuTitleDetailSize : kMenuTitleDetailSize)), - ), - ), - ), - ); - }, + //color: Colors.orange, + child: SizedBox( + width: double.infinity, + child: Align( + alignment: Alignment.centerRight, + child: HtmlWidget( + snapshot.data[index].title.firstWhere((translation) => translation.language == appContext.getContext().language).value, + customStylesBuilder: (element) { + return {'text-align': 'right'}; + }, + textStyle: TextStyle(fontSize: 25),//calculateFontSize(constraints.maxWidth, constraints.maxHeight, kIsWeb ? kWebMenuTitleDetailSize : kMenuTitleDetailSize)), + ), + ), + ), + ), + Container( + //color: Colors.red, + child: SizedBox( + width: double.infinity, + child: Align( + alignment: Alignment.centerRight, + child: HtmlWidget( + snapshot.data[index].description.firstWhere((translation) => translation.language == appContext.getContext().language).value, + customStylesBuilder: (element) { + return {'text-align': 'right'}; + }, + textStyle: TextStyle(fontSize: 20),//calculateFontSize(constraints.maxWidth, constraints.maxHeight, kIsWeb ? kWebMenuTitleDetailSize : kMenuTitleDetailSize)), + ), + ), ), ), - Container(color: Colors.orange, child: Text("ds")), /*Container( color: Colors.orange, @@ -366,6 +428,7 @@ class _MainViewWidget extends State { ConfigurationDTO? configurationDTO = await tabletAppContext.clientAPI!.configurationApi!.configurationGetDetail(tabletAppContext.configuration!.id!); tabletAppContext.configuration = configurationDTO; + backgroundColor = tabletAppContext.configuration != null ? new Color(int.parse(appContext.getContext().configuration.secondaryColor.split('(0x')[1].split(')')[0], radix: 16)) : Colors.white; TabletAppContext? localContext = await DatabaseHelper.instance.getData(); if (localContext != null) { // Check if sql DB exist @@ -441,7 +504,7 @@ boxDecoration(SectionDTO section, bool isSelected) { borderRadius: BorderRadius.circular(30.0), 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.5), BlendMode.dstATop) : null, + colorFilter: !isSelected? new ColorFilter.mode(Colors.black.withOpacity(kIsWeb ? 0.3 : 0.3), BlendMode.dstATop) : null, image: new NetworkImage( section.imageSource!, ), diff --git a/lib/Screens/Puzzle/message_dialog.dart b/lib/Screens/Puzzle/message_dialog.dart index f60d0fa..775d3f4 100644 --- a/lib/Screens/Puzzle/message_dialog.dart +++ b/lib/Screens/Puzzle/message_dialog.dart @@ -29,7 +29,7 @@ void showMessage(TranslationAndResourceDTO translationAndResourceDTO, AppContext borderRadius: BorderRadius.circular(30), //border: Border.all(width: 3, color: Colors.black) ), - child: showElementForResource(ResourceDTO(id: translationAndResourceDTO.resourceId, type: translationAndResourceDTO.resourceType, url: translationAndResourceDTO.resourceUrl), appContext), + child: showElementForResource(ResourceDTO(id: translationAndResourceDTO.resourceId, type: translationAndResourceDTO.resourceType, url: translationAndResourceDTO.resourceUrl), appContext, true, false), ), ), ), diff --git a/lib/Screens/Puzzle/puzzle_view.dart b/lib/Screens/Puzzle/puzzle_view.dart index bdb1cac..1fc7adf 100644 --- a/lib/Screens/Puzzle/puzzle_view.dart +++ b/lib/Screens/Puzzle/puzzle_view.dart @@ -27,17 +27,12 @@ class _PuzzleView extends State { int allInPlaceCount = 0; bool isFinished = false; - GlobalKey _widgetKey = GlobalKey(); Size? realWidgetSize; - - //File? _image; - String? _imagePath; List pieces = []; bool isSplittingImage = true; - @override void initState() { puzzleDTO = PuzzleDTO.fromJson(jsonDecode(widget.section!.data!))!; @@ -77,7 +72,7 @@ class _PuzzleView extends State { // we need to find out the image size, to be used in the PuzzlePiece widget Future getImageSize(Image image) async { - final Completer completer = Completer(); + Completer completer = Completer(); image.image .resolve(const ImageConfiguration()) @@ -86,7 +81,7 @@ class _PuzzleView extends State { Size(info.image.width.toDouble(), info.image.height.toDouble())); })); - final Size imageSize = await completer.future; + Size imageSize = await completer.future; return imageSize; } diff --git a/lib/Screens/Slider/slider_view.dart b/lib/Screens/Slider/slider_view.dart index c2fbeff..4fd6a0f 100644 --- a/lib/Screens/Slider/slider_view.dart +++ b/lib/Screens/Slider/slider_view.dart @@ -23,7 +23,7 @@ class SliderView extends StatefulWidget { class _SliderView extends State { SliderDTO sliderDTO = SliderDTO(); CarouselController? sliderController; - int currentIndex = 1; + ValueNotifier currentIndex = ValueNotifier(1); late ConfigurationDTO configurationDTO; @@ -52,124 +52,116 @@ class _SliderView extends State { return Stack( children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - if(sliderDTO.contents != null && sliderDTO.contents!.length > 0) - CarouselSlider( - carouselController: sliderController, - options: CarouselOptions( - onPageChanged: (int index, CarouselPageChangedReason reason) { - setState(() { - currentIndex = index + 1; - }); - }, - height: MediaQuery.of(context).size.height * 0.8, - enlargeCenterPage: true, - reverse: false, - ), - items: sliderDTO.contents!.map((i) { - return Builder( - builder: (BuildContext context) { - return Container( - width: MediaQuery.of(context).size.width, - height: MediaQuery.of(context).size.height, - margin: EdgeInsets.symmetric(horizontal: 5.0), - decoration: BoxDecoration( - color: configurationDTO.imageId == null ? configurationDTO.secondaryColor != null ? new Color(int.parse(configurationDTO.secondaryColor!.split('(0x')[1].split(')')[0], radix: 16)): kBackgroundGrey : null, - borderRadius: BorderRadius.circular(10.0), - //border: Border.all(width: 0.3, color: kSecondGrey), - ), - child: Column( - //crossAxisAlignment: CrossAxisAlignment.center, - //mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - Padding( - padding: const EdgeInsets.all(10.0), - child: Container( - height: MediaQuery.of(context).size.height * 0.6, - width: MediaQuery.of(context).size.width * 0.72, - /*decoration: BoxDecoration( - color: kBackgroundLight, - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(20.0), - /*image: i.source_ != null ? new DecorationImage( - fit: BoxFit.cover, - image: new NetworkImage( - i.source_, - ), - ): null,*/ - boxShadow: [ - BoxShadow( - color: kBackgroundSecondGrey, - spreadRadius: 0.5, - blurRadius: 5, - offset: Offset(0, 1.5), // changes position of shadow - ), - ], - ),*/ - child: Stack( - children: [ - getElementForResource(appContext, i), - Positioned( - bottom: 0, - right: 0, - child: Padding( - padding: const EdgeInsets.all(15.0), - child: HtmlWidget( - i.title!.firstWhere((translation) => translation.language == appContext.getContext().language).value != null ? i.title!.firstWhere((translation) => translation.language == appContext.getContext().language).value! : "", - textStyle: TextStyle(fontSize: kIsWeb ? kWebTitleSize : kTitleSize, color: kBackgroundLight), - ), - ) - ) - ] - ),/**/ - ), - ), - Expanded( - child: Padding( - padding: const EdgeInsets.only(bottom: 10), - child: Container( - width: MediaQuery.of(context).size.width *0.65, - height: MediaQuery.of(context).size.height *0.25, - decoration: BoxDecoration( - color: kBackgroundLight, - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(10.0), - boxShadow: [ - BoxShadow( - color: kBackgroundSecondGrey, - spreadRadius: 0.3, - blurRadius: 4, - offset: Offset(0, 2), // changes position of shadow - ), - ], - ), - child: SingleChildScrollView( + if(sliderDTO.contents != null && sliderDTO.contents!.length > 0) + CarouselSlider( + carouselController: sliderController, + options: CarouselOptions( + onPageChanged: (int index, CarouselPageChangedReason reason) { + currentIndex.value = index + 1; + }, + height: MediaQuery.of(context).size.height * 0.8, + enlargeCenterPage: true, + reverse: false, + ), + items: sliderDTO.contents!.map((i) { + return Builder( + builder: (BuildContext context) { + return Container( + width: MediaQuery.of(context).size.width, + height: MediaQuery.of(context).size.height, + margin: EdgeInsets.symmetric(horizontal: 5.0), + decoration: BoxDecoration( + color: configurationDTO.imageId == null ? configurationDTO.secondaryColor != null ? new Color(int.parse(configurationDTO.secondaryColor!.split('(0x')[1].split(')')[0], radix: 16)): kBackgroundGrey : null, + borderRadius: BorderRadius.circular(10.0), + //border: Border.all(width: 0.3, color: kSecondGrey), + ), + child: Column( + //crossAxisAlignment: CrossAxisAlignment.center, + //mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Padding( + padding: const EdgeInsets.all(10.0), + child: Container( + height: MediaQuery.of(context).size.height * 0.6, + width: MediaQuery.of(context).size.width * 0.72, + /*decoration: BoxDecoration( + color: kBackgroundLight, + shape: BoxShape.rectangle, + borderRadius: BorderRadius.circular(20.0), + /*image: i.source_ != null ? new DecorationImage( + fit: BoxFit.cover, + image: new NetworkImage( + i.source_, + ), + ): null,*/ + boxShadow: [ + BoxShadow( + color: kBackgroundSecondGrey, + spreadRadius: 0.5, + blurRadius: 5, + offset: Offset(0, 1.5), // changes position of shadow + ), + ], + ),*/ + child: Stack( + children: [ + getElementForResource(appContext, i), + Positioned( + bottom: 0, + right: 0, child: Padding( padding: const EdgeInsets.all(15.0), child: HtmlWidget( - i.description!.firstWhere((translation) => translation.language == appContext.getContext().language).value != null ? i.description!.firstWhere((translation) => translation.language == appContext.getContext().language).value! : "", - textStyle: TextStyle(fontSize: kIsWeb ? kWebDescriptionSize : kDescriptionSize), - customStylesBuilder: (element) { - return {'text-align': 'center'}; - }, + i.title!.firstWhere((translation) => translation.language == appContext.getContext().language).value != null ? i.title!.firstWhere((translation) => translation.language == appContext.getContext().language).value! : "", + textStyle: TextStyle(fontSize: kIsWeb ? kWebTitleSize : kTitleSize, color: kBackgroundLight), ), - ), + ) + ) + ] + ),/**/ + ), + ), + Expanded( + child: Padding( + padding: const EdgeInsets.only(bottom: 10), + child: Container( + width: MediaQuery.of(context).size.width *0.65, + height: MediaQuery.of(context).size.height *0.25, + decoration: BoxDecoration( + color: kBackgroundLight, + shape: BoxShape.rectangle, + borderRadius: BorderRadius.circular(10.0), + boxShadow: [ + BoxShadow( + color: kBackgroundSecondGrey, + spreadRadius: 0.3, + blurRadius: 4, + offset: Offset(0, 2), // changes position of shadow + ), + ], + ), + child: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.all(15.0), + child: HtmlWidget( + i.description!.firstWhere((translation) => translation.language == appContext.getContext().language).value != null ? i.description!.firstWhere((translation) => translation.language == appContext.getContext().language).value! : "", + textStyle: TextStyle(fontSize: kIsWeb ? kWebDescriptionSize : kDescriptionSize), + customStylesBuilder: (element) { + return {'text-align': 'center'}; + }, ), ), ), ), - ], - ) - ); - }, + ), + ), + ], + ) ); - }).toList(), - ), - ], - ), + }, + ); + }).toList(), + ), if(sliderDTO.contents != null && sliderDTO.contents!.length > 1) Positioned( top: MediaQuery.of(context).size.height * 0.35, @@ -211,9 +203,14 @@ class _SliderView extends State { onTap: () { sliderController!.previousPage(duration: new Duration(milliseconds: 500), curve: Curves.fastOutSlowIn); }, - child: Text( - currentIndex.toString()+'/'+sliderDTO.contents!.length.toString(), - style: TextStyle(fontSize: 25, fontWeight: FontWeight.w500), + child: ValueListenableBuilder( + valueListenable: currentIndex, + builder: (context, value, _) { + return Text( + value.toString()+'/'+sliderDTO.contents!.length.toString(), + style: TextStyle(fontSize: 25, fontWeight: FontWeight.w500), + ); + } ), ) ), @@ -250,10 +247,6 @@ class _SliderView extends State { getElementForResource(AppContext appContext, ContentDTO i) { var widgetToInclude; - print("TTTTTTTTTTTTTTESSSSSSSSSSSt CONTENTR"); - print(i); - print(i.resourceUrl); - print(i.resourceType); switch(i.resourceType) { case ResourceType.Image: @@ -274,13 +267,17 @@ class _SliderView extends State { case ResourceType.Video: case ResourceType.VideoUrl: case ResourceType.Audio: - widgetToInclude = showElementForResource(ResourceDTO(id: i.resourceId, url: i.resourceUrl, type: i.resourceType), appContext); + widgetToInclude = Container( + decoration: BoxDecoration( + color: kBackgroundSecondGrey, + shape: BoxShape.rectangle, + borderRadius: BorderRadius.circular(15.0), + ), + child: showElementForResource(ResourceDTO(id: i.resourceId, url: i.resourceUrl, type: i.resourceType), appContext, false, true), + ); break; } - print("TTTTTTTTTTTTTTESSSSSSSSSSSt"); - print(widgetToInclude); - return Center( child: Container( height: MediaQuery.of(context).size.height * 0.6,