Add copy carousel + update many packages.. + linked changes + update price position (geopoint)

This commit is contained in:
Thomas Fransolet 2024-06-21 16:40:31 +02:00
parent fea8e11236
commit 7cffe9db6c
23 changed files with 1064 additions and 183 deletions

View File

@ -0,0 +1,149 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'carousel_options.dart';
import 'carousel_state.dart';
import 'utils.dart';
abstract class CarouselController {
bool get ready;
Future<Null> get onReady;
Future<void> nextPage({Duration? duration, Curve? curve});
Future<void> previousPage({Duration? duration, Curve? curve});
void jumpToPage(int page);
Future<void> animateToPage(int page, {Duration? duration, Curve? curve});
void startAutoPlay();
void stopAutoPlay();
factory CarouselController() => CarouselControllerImpl();
}
class CarouselControllerImpl implements CarouselController {
final Completer<Null> _readyCompleter = Completer<Null>();
CarouselState? _state;
set state(CarouselState? state) {
_state = state;
if (!_readyCompleter.isCompleted) {
_readyCompleter.complete();
}
}
void _setModeController() =>
_state!.changeMode(CarouselPageChangedReason.controller);
@override
bool get ready => _state != null;
@override
Future<Null> get onReady => _readyCompleter.future;
/// Animates the controlled [CarouselSlider] to the next page.
///
/// The animation lasts for the given duration and follows the given curve.
/// The returned [Future] resolves when the animation completes.
Future<void> nextPage(
{Duration? duration = const Duration(milliseconds: 300),
Curve? curve = Curves.linear}) async {
final bool isNeedResetTimer = _state!.options.pauseAutoPlayOnManualNavigate;
if (isNeedResetTimer) {
_state!.onResetTimer();
}
_setModeController();
await _state!.pageController!.nextPage(duration: duration!, curve: curve!);
if (isNeedResetTimer) {
_state!.onResumeTimer();
}
}
/// Animates the controlled [CarouselSlider] to the previous page.
///
/// The animation lasts for the given duration and follows the given curve.
/// The returned [Future] resolves when the animation completes.
Future<void> previousPage(
{Duration? duration = const Duration(milliseconds: 300),
Curve? curve = Curves.linear}) async {
final bool isNeedResetTimer = _state!.options.pauseAutoPlayOnManualNavigate;
if (isNeedResetTimer) {
_state!.onResetTimer();
}
_setModeController();
await _state!.pageController!
.previousPage(duration: duration!, curve: curve!);
if (isNeedResetTimer) {
_state!.onResumeTimer();
}
}
/// Changes which page is displayed in the controlled [CarouselSlider].
///
/// Jumps the page position from its current value to the given value,
/// without animation, and without checking if the new value is in range.
void jumpToPage(int page) {
final index = getRealIndex(_state!.pageController!.page!.toInt(),
_state!.realPage - _state!.initialPage, _state!.itemCount);
_setModeController();
final int pageToJump = _state!.pageController!.page!.toInt() + page - index;
return _state!.pageController!.jumpToPage(pageToJump);
}
/// Animates the controlled [CarouselSlider] from the current page to the given page.
///
/// The animation lasts for the given duration and follows the given curve.
/// The returned [Future] resolves when the animation completes.
Future<void> animateToPage(int page,
{Duration? duration = const Duration(milliseconds: 300),
Curve? curve = Curves.linear}) async {
final bool isNeedResetTimer = _state!.options.pauseAutoPlayOnManualNavigate;
if (isNeedResetTimer) {
_state!.onResetTimer();
}
final index = getRealIndex(_state!.pageController!.page!.toInt(),
_state!.realPage - _state!.initialPage, _state!.itemCount);
int smallestMovement = page - index;
if (_state!.options.enableInfiniteScroll &&
_state!.itemCount != null &&
_state!.options.animateToClosest) {
if ((page - index).abs() > (page + _state!.itemCount! - index).abs()) {
smallestMovement = page + _state!.itemCount! - index;
} else if ((page - index).abs() >
(page - _state!.itemCount! - index).abs()) {
smallestMovement = page - _state!.itemCount! - index;
}
}
_setModeController();
await _state!.pageController!.animateToPage(
_state!.pageController!.page!.toInt() + smallestMovement,
duration: duration!,
curve: curve!);
if (isNeedResetTimer) {
_state!.onResumeTimer();
}
}
/// Starts the controlled [CarouselSlider] autoplay.
///
/// The carousel will only autoPlay if the [autoPlay] parameter
/// in [CarouselOptions] is true.
void startAutoPlay() {
_state!.onResumeTimer();
}
/// Stops the controlled [CarouselSlider] from autoplaying.
///
/// This is a more on-demand way of doing this. Use the [autoPlay]
/// parameter in [CarouselOptions] to specify the autoPlay behaviour of the carousel.
void stopAutoPlay() {
_state!.onResetTimer();
}
}

View File

@ -0,0 +1,223 @@
import 'package:flutter/material.dart';
enum CarouselPageChangedReason { timed, manual, controller }
enum CenterPageEnlargeStrategy { scale, height, zoom }
class CarouselOptions {
/// Set carousel height and overrides any existing [aspectRatio].
final double? height;
/// Aspect ratio is used if no height have been declared.
///
/// Defaults to 16:9 aspect ratio.
final double aspectRatio;
/// The fraction of the viewport that each page should occupy.
///
/// Defaults to 0.8, which means each page fills 80% of the carousel.
final double viewportFraction;
/// The initial page to show when first creating the [CarouselSlider].
///
/// Defaults to 0.
final int initialPage;
///Determines if carousel should loop infinitely or be limited to item length.
///
///Defaults to true, i.e. infinite loop.
final bool enableInfiniteScroll;
///Determines if carousel should loop to the closest occurence of requested page.
///
///Defaults to true.
final bool animateToClosest;
/// Reverse the order of items if set to true.
///
/// Defaults to false.
final bool reverse;
/// Enables auto play, sliding one page at a time.
///
/// Use [autoPlayInterval] to determent the frequency of slides.
/// Defaults to false.
final bool autoPlay;
/// Sets Duration to determent the frequency of slides when
///
/// [autoPlay] is set to true.
/// Defaults to 4 seconds.
final Duration autoPlayInterval;
/// The animation duration between two transitioning pages while in auto playback.
///
/// Defaults to 800 ms.
final Duration autoPlayAnimationDuration;
/// Determines the animation curve physics.
///
/// Defaults to [Curves.fastOutSlowIn].
final Curve autoPlayCurve;
/// Determines if current page should be larger than the side images,
/// creating a feeling of depth in the carousel.
///
/// Defaults to false.
final bool? enlargeCenterPage;
/// The axis along which the page view scrolls.
///
/// Defaults to [Axis.horizontal].
final Axis scrollDirection;
/// Called whenever the page in the center of the viewport changes.
final Function(int index, CarouselPageChangedReason reason)? onPageChanged;
/// Called whenever the carousel is scrolled
final ValueChanged<double?>? onScrolled;
/// How the carousel should respond to user input.
///
/// For example, determines how the items continues to animate after the
/// user stops dragging the page view.
///
/// The physics are modified to snap to page boundaries using
/// [PageScrollPhysics] prior to being used.
///
/// Defaults to matching platform conventions.
final ScrollPhysics? scrollPhysics;
/// Set to false to disable page snapping, useful for custom scroll behavior.
///
/// Default to `true`.
final bool pageSnapping;
/// If `true`, the auto play function will be paused when user is interacting with
/// the carousel, and will be resumed when user finish interacting.
/// Default to `true`.
final bool pauseAutoPlayOnTouch;
/// If `true`, the auto play function will be paused when user is calling
/// pageController's `nextPage` or `previousPage` or `animateToPage` method.
/// And after the animation complete, the auto play will be resumed.
/// Default to `true`.
final bool pauseAutoPlayOnManualNavigate;
/// If `enableInfiniteScroll` is `false`, and `autoPlay` is `true`, this option
/// decide the carousel should go to the first item when it reach the last item or not.
/// If set to `true`, the auto play will be paused when it reach the last item.
/// If set to `false`, the auto play function will animate to the first item when it was
/// in the last item.
final bool pauseAutoPlayInFiniteScroll;
/// Pass a `PageStoragekey` if you want to keep the pageview's position when it was recreated.
final PageStorageKey? pageViewKey;
/// Use [enlargeStrategy] to determine which method to enlarge the center page.
final CenterPageEnlargeStrategy enlargeStrategy;
/// How much the pages next to the center page will be scaled down.
/// If `enlargeCenterPage` is false, this property has no effect.
final double enlargeFactor;
/// Whether or not to disable the `Center` widget for each slide.
final bool disableCenter;
/// Whether to add padding to both ends of the list.
/// If this is set to true and [viewportFraction] < 1.0, padding will be added such that the first and last child slivers will be in the center of the viewport when scrolled all the way to the start or end, respectively.
/// If [viewportFraction] >= 1.0, this property has no effect.
/// This property defaults to true and must not be null.
final bool padEnds;
/// Exposed clipBehavior of PageView
final Clip clipBehavior;
CarouselOptions({
this.height,
this.aspectRatio = 16 / 9,
this.viewportFraction = 0.8,
this.initialPage = 0,
this.enableInfiniteScroll = true,
this.animateToClosest = true,
this.reverse = false,
this.autoPlay = false,
this.autoPlayInterval = const Duration(seconds: 4),
this.autoPlayAnimationDuration = const Duration(milliseconds: 800),
this.autoPlayCurve = Curves.fastOutSlowIn,
this.enlargeCenterPage = false,
this.onPageChanged,
this.onScrolled,
this.scrollPhysics,
this.pageSnapping = true,
this.scrollDirection = Axis.horizontal,
this.pauseAutoPlayOnTouch = true,
this.pauseAutoPlayOnManualNavigate = true,
this.pauseAutoPlayInFiniteScroll = false,
this.pageViewKey,
this.enlargeStrategy = CenterPageEnlargeStrategy.scale,
this.enlargeFactor = 0.3,
this.disableCenter = false,
this.padEnds = true,
this.clipBehavior = Clip.hardEdge,
});
///Generate new [CarouselOptions] based on old ones.
CarouselOptions copyWith(
{double? height,
double? aspectRatio,
double? viewportFraction,
int? initialPage,
bool? enableInfiniteScroll,
bool? reverse,
bool? autoPlay,
Duration? autoPlayInterval,
Duration? autoPlayAnimationDuration,
Curve? autoPlayCurve,
bool? enlargeCenterPage,
Function(int index, CarouselPageChangedReason reason)? onPageChanged,
ValueChanged<double?>? onScrolled,
ScrollPhysics? scrollPhysics,
bool? pageSnapping,
Axis? scrollDirection,
bool? pauseAutoPlayOnTouch,
bool? pauseAutoPlayOnManualNavigate,
bool? pauseAutoPlayInFiniteScroll,
PageStorageKey? pageViewKey,
CenterPageEnlargeStrategy? enlargeStrategy,
double? enlargeFactor,
bool? disableCenter,
Clip? clipBehavior,
bool? padEnds}) =>
CarouselOptions(
height: height ?? this.height,
aspectRatio: aspectRatio ?? this.aspectRatio,
viewportFraction: viewportFraction ?? this.viewportFraction,
initialPage: initialPage ?? this.initialPage,
enableInfiniteScroll: enableInfiniteScroll ?? this.enableInfiniteScroll,
reverse: reverse ?? this.reverse,
autoPlay: autoPlay ?? this.autoPlay,
autoPlayInterval: autoPlayInterval ?? this.autoPlayInterval,
autoPlayAnimationDuration:
autoPlayAnimationDuration ?? this.autoPlayAnimationDuration,
autoPlayCurve: autoPlayCurve ?? this.autoPlayCurve,
enlargeCenterPage: enlargeCenterPage ?? this.enlargeCenterPage,
onPageChanged: onPageChanged ?? this.onPageChanged,
onScrolled: onScrolled ?? this.onScrolled,
scrollPhysics: scrollPhysics ?? this.scrollPhysics,
pageSnapping: pageSnapping ?? this.pageSnapping,
scrollDirection: scrollDirection ?? this.scrollDirection,
pauseAutoPlayOnTouch: pauseAutoPlayOnTouch ?? this.pauseAutoPlayOnTouch,
pauseAutoPlayOnManualNavigate:
pauseAutoPlayOnManualNavigate ?? this.pauseAutoPlayOnManualNavigate,
pauseAutoPlayInFiniteScroll:
pauseAutoPlayInFiniteScroll ?? this.pauseAutoPlayInFiniteScroll,
pageViewKey: pageViewKey ?? this.pageViewKey,
enlargeStrategy: enlargeStrategy ?? this.enlargeStrategy,
enlargeFactor: enlargeFactor ?? this.enlargeFactor,
disableCenter: disableCenter ?? this.disableCenter,
clipBehavior: clipBehavior ?? this.clipBehavior,
padEnds: padEnds ?? this.padEnds,
);
}

View File

@ -0,0 +1,396 @@
import 'dart:async';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'carousel_controller.dart' as cs;
import 'carousel_options.dart';
import 'carousel_state.dart';
import 'utils.dart';
export 'carousel_controller.dart';
export 'carousel_options.dart';
typedef Widget ExtendedIndexedWidgetBuilder(
BuildContext context, int index, int realIndex);
class CarouselSlider extends StatefulWidget {
/// [CarouselOptions] to create a [CarouselState] with
final CarouselOptions options;
final bool? disableGesture;
/// The widgets to be shown in the carousel of default constructor
final List<Widget>? items;
/// The widget item builder that will be used to build item on demand
/// The third argument is the PageView's real index, can be used to cooperate
/// with Hero.
final ExtendedIndexedWidgetBuilder? itemBuilder;
/// A [MapController], used to control the map.
final cs.CarouselControllerImpl _carouselController;
final int? itemCount;
CarouselSlider(
{required this.items,
required this.options,
this.disableGesture,
cs.CarouselController? carouselController,
Key? key})
: itemBuilder = null,
itemCount = items != null ? items.length : 0,
_carouselController = carouselController != null
? carouselController as cs.CarouselControllerImpl
: cs.CarouselController() as cs.CarouselControllerImpl,
super(key: key);
/// The on demand item builder constructor
CarouselSlider.builder(
{required this.itemCount,
required this.itemBuilder,
required this.options,
this.disableGesture,
cs.CarouselController? carouselController,
Key? key})
: items = null,
_carouselController = carouselController != null
? carouselController as cs.CarouselControllerImpl
: CarouselController() as cs.CarouselControllerImpl,
super(key: key);
@override
CarouselSliderState createState() => CarouselSliderState(_carouselController);
}
class CarouselSliderState extends State<CarouselSlider>
with TickerProviderStateMixin {
final cs.CarouselControllerImpl carouselController;
Timer? timer;
CarouselOptions get options => widget.options;
CarouselState? carouselState;
PageController? pageController;
/// mode is related to why the page is being changed
CarouselPageChangedReason mode = CarouselPageChangedReason.controller;
CarouselSliderState(this.carouselController);
void changeMode(CarouselPageChangedReason _mode) {
mode = _mode;
}
@override
void didUpdateWidget(CarouselSlider oldWidget) {
carouselState!.options = options;
carouselState!.itemCount = widget.itemCount;
// pageController needs to be re-initialized to respond to state changes
pageController = PageController(
viewportFraction: options.viewportFraction,
initialPage: carouselState!.realPage,
);
carouselState!.pageController = pageController;
// handle autoplay when state changes
handleAutoPlay();
super.didUpdateWidget(oldWidget);
}
@override
void initState() {
super.initState();
carouselState =
CarouselState(this.options, clearTimer, resumeTimer, this.changeMode);
carouselState!.itemCount = widget.itemCount;
carouselController.state = carouselState;
carouselState!.initialPage = widget.options.initialPage;
carouselState!.realPage = options.enableInfiniteScroll
? carouselState!.realPage + carouselState!.initialPage
: carouselState!.initialPage;
handleAutoPlay();
pageController = PageController(
viewportFraction: options.viewportFraction,
initialPage: carouselState!.realPage,
);
carouselState!.pageController = pageController;
}
Timer? getTimer() {
return widget.options.autoPlay
? Timer.periodic(widget.options.autoPlayInterval, (_) {
if (!mounted) {
clearTimer();
return;
}
final route = ModalRoute.of(context);
if (route?.isCurrent == false) {
return;
}
CarouselPageChangedReason previousReason = mode;
changeMode(CarouselPageChangedReason.timed);
int nextPage = carouselState!.pageController!.page!.round() + 1;
int itemCount = widget.itemCount ?? widget.items!.length;
if (nextPage >= itemCount &&
widget.options.enableInfiniteScroll == false) {
if (widget.options.pauseAutoPlayInFiniteScroll) {
clearTimer();
return;
}
nextPage = 0;
}
carouselState!.pageController!
.animateToPage(nextPage,
duration: widget.options.autoPlayAnimationDuration,
curve: widget.options.autoPlayCurve)
.then((_) => changeMode(previousReason));
})
: null;
}
void clearTimer() {
if (timer != null) {
timer?.cancel();
timer = null;
}
}
void resumeTimer() {
if (timer == null) {
timer = getTimer();
}
}
void handleAutoPlay() {
bool autoPlayEnabled = widget.options.autoPlay;
if (autoPlayEnabled && timer != null) return;
clearTimer();
if (autoPlayEnabled) {
resumeTimer();
}
}
Widget getGestureWrapper(Widget child) {
Widget wrapper;
if (widget.options.height != null) {
wrapper = Container(height: widget.options.height, child: child);
} else {
wrapper =
AspectRatio(aspectRatio: widget.options.aspectRatio, child: child);
}
if (true == widget.disableGesture) {
return NotificationListener(
onNotification: (Notification notification) {
if (widget.options.onScrolled != null &&
notification is ScrollUpdateNotification) {
widget.options.onScrolled!(carouselState!.pageController!.page);
}
return false;
},
child: wrapper,
);
}
return RawGestureDetector(
behavior: HitTestBehavior.opaque,
gestures: {
_MultipleGestureRecognizer:
GestureRecognizerFactoryWithHandlers<_MultipleGestureRecognizer>(
() => _MultipleGestureRecognizer(),
(_MultipleGestureRecognizer instance) {
instance.onStart = (_) {
onStart();
};
instance.onDown = (_) {
onPanDown();
};
instance.onEnd = (_) {
onPanUp();
};
instance.onCancel = () {
onPanUp();
};
}),
},
child: NotificationListener(
onNotification: (Notification notification) {
if (widget.options.onScrolled != null &&
notification is ScrollUpdateNotification) {
widget.options.onScrolled!(carouselState!.pageController!.page);
}
return false;
},
child: wrapper,
),
);
}
Widget getCenterWrapper(Widget child) {
if (widget.options.disableCenter) {
return Container(
child: child,
);
}
return Center(child: child);
}
Widget getEnlargeWrapper(Widget? child,
{double? width,
double? height,
double? scale,
required double itemOffset}) {
if (widget.options.enlargeStrategy == CenterPageEnlargeStrategy.height) {
return SizedBox(child: child, width: width, height: height);
}
if (widget.options.enlargeStrategy == CenterPageEnlargeStrategy.zoom) {
late Alignment alignment;
final bool horizontal = options.scrollDirection == Axis.horizontal;
if (itemOffset > 0) {
alignment = horizontal ? Alignment.centerRight : Alignment.bottomCenter;
} else {
alignment = horizontal ? Alignment.centerLeft : Alignment.topCenter;
}
return Transform.scale(child: child, scale: scale!, alignment: alignment);
}
return Transform.scale(
scale: scale!,
child: Container(child: child, width: width, height: height));
}
void onStart() {
changeMode(CarouselPageChangedReason.manual);
}
void onPanDown() {
if (widget.options.pauseAutoPlayOnTouch) {
clearTimer();
}
changeMode(CarouselPageChangedReason.manual);
}
void onPanUp() {
if (widget.options.pauseAutoPlayOnTouch) {
resumeTimer();
}
}
@override
void dispose() {
super.dispose();
clearTimer();
}
@override
Widget build(BuildContext context) {
return getGestureWrapper(PageView.builder(
padEnds: widget.options.padEnds,
scrollBehavior: ScrollConfiguration.of(context).copyWith(
scrollbars: false,
overscroll: false,
dragDevices: {
PointerDeviceKind.touch,
PointerDeviceKind.mouse,
},
),
clipBehavior: widget.options.clipBehavior,
physics: widget.options.scrollPhysics,
scrollDirection: widget.options.scrollDirection,
pageSnapping: widget.options.pageSnapping,
controller: carouselState!.pageController,
reverse: widget.options.reverse,
itemCount: widget.options.enableInfiniteScroll ? null : widget.itemCount,
key: widget.options.pageViewKey,
onPageChanged: (int index) {
int currentPage = getRealIndex(index + carouselState!.initialPage,
carouselState!.realPage, widget.itemCount);
if (widget.options.onPageChanged != null) {
widget.options.onPageChanged!(currentPage, mode);
}
},
itemBuilder: (BuildContext context, int idx) {
final int index = getRealIndex(idx + carouselState!.initialPage,
carouselState!.realPage, widget.itemCount);
return AnimatedBuilder(
animation: carouselState!.pageController!,
child: (widget.items != null)
? (widget.items!.length > 0 ? widget.items![index] : Container())
: widget.itemBuilder!(context, index, idx),
builder: (BuildContext context, child) {
double distortionValue = 1.0;
// if `enlargeCenterPage` is true, we must calculate the carousel item's height
// to display the visual effect
double itemOffset = 0;
if (widget.options.enlargeCenterPage != null &&
widget.options.enlargeCenterPage == true) {
// pageController.page can only be accessed after the first build,
// so in the first build we calculate the itemoffset manually
var position = carouselState?.pageController?.position;
if (position != null &&
position.hasPixels &&
position.hasContentDimensions) {
var _page = carouselState?.pageController?.page;
if (_page != null) {
itemOffset = _page - idx;
}
} else {
BuildContext storageContext = carouselState!
.pageController!.position.context.storageContext;
final double? previousSavedPosition =
PageStorage.of(storageContext)?.readState(storageContext)
as double?;
if (previousSavedPosition != null) {
itemOffset = previousSavedPosition - idx.toDouble();
} else {
itemOffset =
carouselState!.realPage.toDouble() - idx.toDouble();
}
}
final double enlargeFactor =
options.enlargeFactor.clamp(0.0, 1.0);
final num distortionRatio =
(1 - (itemOffset.abs() * enlargeFactor)).clamp(0.0, 1.0);
distortionValue =
Curves.easeOut.transform(distortionRatio as double);
}
final double height = widget.options.height ??
MediaQuery.of(context).size.width *
(1 / widget.options.aspectRatio);
if (widget.options.scrollDirection == Axis.horizontal) {
return getCenterWrapper(getEnlargeWrapper(child,
height: distortionValue * height,
scale: distortionValue,
itemOffset: itemOffset));
} else {
return getCenterWrapper(getEnlargeWrapper(child,
width: distortionValue * MediaQuery.of(context).size.width,
scale: distortionValue,
itemOffset: itemOffset));
}
},
);
},
));
}
}
class _MultipleGestureRecognizer extends PanGestureRecognizer {}

View File

@ -0,0 +1,43 @@
import 'package:flutter/material.dart';
import 'carousel_options.dart';
class CarouselState {
/// The [CarouselOptions] to create this state
CarouselOptions options;
/// [pageController] is created using the properties passed to the constructor
/// and can be used to control the [PageView] it is passed to.
PageController? pageController;
/// The actual index of the [PageView].
///
/// This value can be ignored unless you know the carousel will be scrolled
/// backwards more then 10000 pages.
/// Defaults to 10000 to simulate infinite backwards scrolling.
int realPage = 10000;
/// The initial index of the [PageView] on [CarouselSlider] init.
///
int initialPage = 0;
/// The widgets count that should be shown at carousel
int? itemCount;
/// Will be called when using pageController to go to next page or
/// previous page. It will clear the autoPlay timer.
/// Internal use only
Function onResetTimer;
/// Will be called when using pageController to go to next page or
/// previous page. It will restart the autoPlay timer.
/// Internal use only
Function onResumeTimer;
/// The callback to set the Reason Carousel changed
Function(CarouselPageChangedReason) changeMode;
CarouselState(
this.options, this.onResetTimer, this.onResumeTimer, this.changeMode);
}

View File

@ -0,0 +1,23 @@
/// Converts an index of a set size to the corresponding index of a collection of another size
/// as if they were circular.
///
/// Takes a [position] from collection Foo, a [base] from where Foo's index originated
/// and the [length] of a second collection Baa, for which the correlating index is sought.
///
/// For example; We have a Carousel of 10000(simulating infinity) but only 6 images.
/// We need to repeat the images to give the illusion of a never ending stream.
/// By calling _getRealIndex with position and base we get an offset.
/// This offset modulo our length, 6, will return a number between 0 and 5, which represent the image
/// to be placed in the given position.
int getRealIndex(int position, int base, int? length) {
final int offset = position - base;
return remainder(offset, length);
}
/// Returns the remainder of the modulo operation [input] % [source], and adjust it for
/// negative values.
int remainder(int input, int? source) {
if (source == 0) return 0;
final int result = input % source!;
return result < 0 ? source + result : result;
}

View File

@ -1,9 +1,9 @@
import 'dart:io'; import 'dart:io';
import 'package:cached_video_player/cached_video_player.dart'; //import 'package:cached_video_player/cached_video_player.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:tablet_app/Components/loading_common.dart'; import 'package:tablet_app/Components/loading_common.dart';
//import 'package:video_player/video_player.dart'; import 'package:video_player/video_player.dart';
import '../../constants.dart'; import '../../constants.dart';
class VideoViewer extends StatefulWidget { class VideoViewer extends StatefulWidget {
@ -16,19 +16,19 @@ class VideoViewer extends StatefulWidget {
} }
class _VideoViewer extends State<VideoViewer> { class _VideoViewer extends State<VideoViewer> {
late CachedVideoPlayerController _controller; late VideoPlayerController _controller; // Cached
@override @override
void initState() { void initState() {
super.initState(); super.initState();
if(widget.file != null) { if(widget.file != null) {
_controller = CachedVideoPlayerController.file(widget.file!) // Uri.parse() _controller = VideoPlayerController.file(widget.file!) // Uri.parse() // Cached
..initialize().then((_) { ..initialize().then((_) {
// Ensure the first frame is shown after the video is initialized, even before the play button has been pressed. // Ensure the first frame is shown after the video is initialized, even before the play button has been pressed.
setState(() {}); setState(() {});
}); });
} else { } else {
_controller = CachedVideoPlayerController.network(widget.videoUrl) // Uri.parse() _controller = VideoPlayerController.networkUrl(Uri.parse(widget.videoUrl)) // Uri.parse()
..initialize().then((_) { ..initialize().then((_) {
// Ensure the first frame is shown after the video is initialized, even before the play button has been pressed. // Ensure the first frame is shown after the video is initialized, even before the play button has been pressed.
setState(() {}); setState(() {});
@ -62,7 +62,7 @@ class _VideoViewer extends State<VideoViewer> {
child: _controller.value.isInitialized child: _controller.value.isInitialized
? AspectRatio( ? AspectRatio(
aspectRatio: _controller.value.aspectRatio, aspectRatio: _controller.value.aspectRatio,
child: CachedVideoPlayer(_controller), child: VideoPlayer(_controller),
) )
: Center( : Center(
child: Container( child: Container(

View File

@ -1,6 +1,7 @@
import 'dart:io'; import 'dart:io';
import 'package:device_info/device_info.dart'; //import 'package:device_info/device_info.dart';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
class DeviceInfoHelper { class DeviceInfoHelper {
@ -12,15 +13,11 @@ class DeviceInfoHelper {
try { try {
if (Platform.isAndroid) { if (Platform.isAndroid) {
var build = await deviceInfoPlugin.androidInfo; var build = await deviceInfoPlugin.androidInfo;
/*deviceName = build.model; identifier = build.id; //UUID for Android
deviceVersion = build.version.toString();*/
identifier = build.androidId; //UUID for Android
print(identifier); print(identifier);
} else if (Platform.isIOS) { } else if (Platform.isIOS) {
var data = await deviceInfoPlugin.iosInfo; var data = await deviceInfoPlugin.iosInfo;
/*deviceName = data.name;
deviceVersion = data.systemVersion;*/
identifier = data.identifierForVendor; //UUID for iOS identifier = data.identifierForVendor; //UUID for iOS
} }
} on PlatformException { } on PlatformException {

View File

@ -76,7 +76,7 @@ class _EventPopupState extends State<EventPopup> {
coordinates: mapBox.Position( coordinates: mapBox.Position(
position.longitude, position.longitude,
position.latitude, position.latitude,
)).toJson(), )), // .toJson()
iconSize: 1.3, iconSize: 1.3,
iconOffset: [0.0, 0.0], iconOffset: [0.0, 0.0],
symbolSortKey: 10, symbolSortKey: 10,
@ -299,7 +299,7 @@ class _EventPopupState extends State<EventPopup> {
_onMapCreated(maBoxMap, widget.mapIcon); _onMapCreated(maBoxMap, widget.mapIcon);
}, },
cameraOptions: mapBox.CameraOptions( cameraOptions: mapBox.CameraOptions(
center: mapBox.Point(coordinates: mapBox.Position(double.parse(widget.eventAgenda.address!.lng!.toString()), double.parse(widget.eventAgenda.address!.lat!.toString()))).toJson(), center: mapBox.Point(coordinates: mapBox.Position(double.parse(widget.eventAgenda.address!.lng!.toString()), double.parse(widget.eventAgenda.address!.lat!.toString()))), // .toJson()
zoom: 14 zoom: 14
), ),
), ),

View File

@ -375,7 +375,7 @@ class _MainViewWidget extends State<MainViewWidget> {
flex: 2, flex: 2,
child: Center( child: Center(
child: HtmlWidget( child: HtmlWidget(
sectionsLocal![index].title!.firstWhere((translation) => translation.language == appContext.getContext().language).value ?? "", sectionsLocal![index].title!.where((translation) => translation.language == appContext.getContext().language).firstOrNull?.value ?? "",
customStylesBuilder: (element) { customStylesBuilder: (element) {
return {'text-align': 'center', 'font-family': "Roboto"}; return {'text-align': 'center', 'font-family': "Roboto"};
}, },

View File

@ -132,15 +132,15 @@ class _SectionPageDetailState extends State<SectionPageDetail> {
Align( Align(
alignment: Alignment.center, alignment: Alignment.center,
child: HtmlWidget( child: HtmlWidget(
widget.sectionDTO.title!.firstWhere((translation) => translation.language == appContext.getContext().language).value!, widget.sectionDTO.title!.where((translation) => translation.language == appContext.getContext().language).firstOrNull?.value ?? "",
textStyle: new TextStyle(fontSize: kIsWeb ? kWebSectionTitleDetailSize : kSectionTitleDetailSize, color: widget.textColor, fontFamily: 'Roboto'), textStyle: new TextStyle(fontSize: kIsWeb ? kWebSectionTitleDetailSize : kSectionTitleDetailSize, color: widget.textColor, fontFamily: 'Roboto'),
) )
), ),
if(widget.sectionDTO.description!.firstWhere((translation) => translation.language == appContext.getContext().language).value != null && widget.sectionDTO.description!.firstWhere((translation) => translation.language == appContext.getContext().language).value!.trim().isNotEmpty) if(widget.sectionDTO.description!.where((translation) => translation.language == appContext.getContext().language).firstOrNull != null && widget.sectionDTO.description!.firstWhere((translation) => translation.language == appContext.getContext().language).value!.trim().isNotEmpty)
Align( Align(
//alignment: Alignment.center, //alignment: Alignment.center,
child: HtmlWidget( child: HtmlWidget(
widget.sectionDTO.description!.firstWhere((translation) => translation.language == appContext.getContext().language).value!, widget.sectionDTO.description!.where((translation) => translation.language == appContext.getContext().language).firstOrNull?.value ?? "",
textStyle: new TextStyle(fontSize: kIsWeb? kWebSectionDescriptionDetailSize : kSectionDescriptionDetailSize, color: widget.textColor, fontFamily: 'Roboto'), textStyle: new TextStyle(fontSize: kIsWeb? kWebSectionDescriptionDetailSize : kSectionDescriptionDetailSize, color: widget.textColor, fontFamily: 'Roboto'),
) )
) )
@ -157,6 +157,7 @@ class _SectionPageDetailState extends State<SectionPageDetail> {
backgroundColor: kBackgroundColor, backgroundColor: kBackgroundColor,
focusColor: kBackgroundColor, focusColor: kBackgroundColor,
splashColor: kBackgroundColor, splashColor: kBackgroundColor,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 30.0)),
onPressed: () { onPressed: () {
Navigator.pop(context); Navigator.pop(context);
/*Navigator.of(context).pushReplacement( /*Navigator.of(context).pushReplacement(

View File

@ -74,7 +74,7 @@ class _GeoPointFilterState extends State<GeoPointFilter> {
// Pour chaque point sans categorie, créer un noeud // Pour chaque point sans categorie, créer un noeud
for(var pointWithoutCat in geoPoints.where((gp) => gp.categorieId == null && gp.categorie == null)) for(var pointWithoutCat in geoPoints.where((gp) => gp.categorieId == null && gp.categorie == null))
{ {
if(pointWithoutCat.title!.where((l) => l.language == widget.language).firstOrNull != null) {
TreeNode nodeWithoutCat = TreeNode( TreeNode nodeWithoutCat = TreeNode(
id: 000 + int.parse( id: 000 + int.parse(
(pointWithoutCat.latitude ?? '').substring(0, min(pointWithoutCat.latitude!.length, 10)).replaceAll(".", "") + (pointWithoutCat.longitude ?? '').substring(0, min(pointWithoutCat.longitude!.length, 10)).replaceAll(".", "") (pointWithoutCat.latitude ?? '').substring(0, min(pointWithoutCat.latitude!.length, 10)).replaceAll(".", "") + (pointWithoutCat.longitude ?? '').substring(0, min(pointWithoutCat.longitude!.length, 10)).replaceAll(".", "")
@ -88,9 +88,12 @@ class _GeoPointFilterState extends State<GeoPointFilter> {
); );
nodes.add(nodeWithoutCat); nodes.add(nodeWithoutCat);
} }
}
// Pour chaque catégorie, créez un nœud parent // Pour chaque catégorie, créez un nœud parent
for (var category in categories) { for (var category in categories) {
if(category.label!.where((l) => l.language == widget.language).firstOrNull != null)
{
TreeNode categoryNode = TreeNode( TreeNode categoryNode = TreeNode(
id: 100 + (category.id ?? 0), id: 100 + (category.id ?? 0),
title: parse(category.label!.firstWhere((l) => l.language == widget.language).value!).documentElement!.text, title: parse(category.label!.firstWhere((l) => l.language == widget.language).value!).documentElement!.text,
@ -103,7 +106,7 @@ class _GeoPointFilterState extends State<GeoPointFilter> {
// Ajoutez les géopoints correspondant à cette catégorie en tant qu'enfants du nœud parent // Ajoutez les géopoints correspondant à cette catégorie en tant qu'enfants du nœud parent
for (var geoPoint in geoPoints.where((gp) => gp.categorie != null || gp.categorieId != null)) { for (var geoPoint in geoPoints.where((gp) => gp.categorie != null || gp.categorieId != null)) {
if (geoPoint.categorieId == category.id) { if (geoPoint.categorieId == category.id && geoPoint.title!.where((l) => l.language == widget.language).firstOrNull != null) {
TreeNode geoPointNode = TreeNode( TreeNode geoPointNode = TreeNode(
id: 000 + int.parse( id: 000 + int.parse(
(geoPoint.latitude ?? '').substring(0, min(geoPoint.latitude!.length, 10)).replaceAll(".", "") + (geoPoint.longitude ?? '').substring(0, min(geoPoint.longitude!.length, 10)).replaceAll(".", "") (geoPoint.latitude ?? '').substring(0, min(geoPoint.latitude!.length, 10)).replaceAll(".", "") + (geoPoint.longitude ?? '').substring(0, min(geoPoint.longitude!.length, 10)).replaceAll(".", "")
@ -121,6 +124,7 @@ class _GeoPointFilterState extends State<GeoPointFilter> {
nodes.add(categoryNode); nodes.add(categoryNode);
} }
}
nodes.sort((a, b) => a.title.compareTo(b.title)); nodes.sort((a, b) => a.title.compareTo(b.title));

View File

@ -60,6 +60,7 @@ class _MapBoxViewState extends State<MapBoxView> {
int i = 0; int i = 0;
markersList = []; markersList = [];
pointsToShow!.forEach((point) { pointsToShow!.forEach((point) {
if(point.title!.where((translation) => translation.language == widget.language).firstOrNull != null) {
var textSansHTML = parse(point.title!.firstWhere((translation) => translation.language == widget.language).value); var textSansHTML = parse(point.title!.firstWhere((translation) => translation.language == widget.language).value);
point.id = i; point.id = i;
point.title = point.title!.where((t) => t.language == widget.language).toList(); point.title = point.title!.where((t) => t.language == widget.language).toList();
@ -77,7 +78,7 @@ class _MapBoxViewState extends State<MapBoxView> {
coordinates: mapBox.Position( coordinates: mapBox.Position(
double.tryParse(point.longitude!)!, double.tryParse(point.longitude!)!,
double.tryParse(point.latitude!)!, double.tryParse(point.latitude!)!,
)).toJson(), )), // .toJson()
iconSize: 1.3, iconSize: 1.3,
textField: "${parse(textSansHTML.body!.text).documentElement!.text}${point.latitude}${point.longitude}", textField: "${parse(textSansHTML.body!.text).documentElement!.text}${point.latitude}${point.longitude}",
textOpacity: 0.0, textOpacity: 0.0,
@ -89,6 +90,7 @@ class _MapBoxViewState extends State<MapBoxView> {
)); // , )); // ,
i++; i++;
}
}); });
print(options.length); print(options.length);
@ -117,7 +119,8 @@ class _MapBoxViewState extends State<MapBoxView> {
@override @override
void initState() { void initState() {
pointsToShow = widget.geoPoints;//widget.mapDTO!.points; pointsToShow = widget.geoPoints;//widget.mapDTO!.points;
selectedCategories = widget.mapDTO!.categories!.map((categorie) => categorie.label!.firstWhere((element) => element.language == widget.language).value!).toList(); var nonNullCat = widget.mapDTO!.categories!.where((c) => c.label!.where((element) => element.language == widget.language).firstOrNull != null);
selectedCategories = nonNullCat.map((categorie) => categorie.label!.firstWhere((element) => element.language == widget.language).value!).toList();
super.initState(); super.initState();
} }
@ -183,7 +186,7 @@ class _MapBoxViewState extends State<MapBoxView> {
mapContext.setSelectedPointForNavigate(null); mapContext.setSelectedPointForNavigate(null);
}, },
cameraOptions: mapBox.CameraOptions( cameraOptions: mapBox.CameraOptions(
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(), 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()
zoom: widget.mapDTO!.zoom != null ? widget.mapDTO!.zoom!.toDouble() : 12), zoom: widget.mapDTO!.zoom != null ? widget.mapDTO!.zoom!.toDouble() : 12),
) )
), ),
@ -197,7 +200,7 @@ class _MapBoxViewState extends State<MapBoxView> {
print("COUCOU IL FAUT NAVUGATE MAPBOX"); print("COUCOU IL FAUT NAVUGATE MAPBOX");
mapboxMap?.easeTo( mapboxMap?.easeTo(
mapBox.CameraOptions( mapBox.CameraOptions(
center: mapBox.Point(coordinates: mapBox.Position(double.tryParse(geoPoint.longitude!)!, double.tryParse(geoPoint.latitude!)!)).toJson(), center: mapBox.Point(coordinates: mapBox.Position(double.tryParse(geoPoint.longitude!)!, double.tryParse(geoPoint.latitude!)!)), //.toJson()
zoom: 16, zoom: 16,
bearing: 0, bearing: 0,
pitch: 3), pitch: 3),

View File

@ -1,6 +1,5 @@
import 'package:auto_size_text/auto_size_text.dart'; import 'package:auto_size_text/auto_size_text.dart';
import 'package:cached_network_image/cached_network_image.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/cupertino.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -9,6 +8,7 @@ import 'package:manager_api/api.dart';
import 'package:photo_view/photo_view.dart'; import 'package:photo_view/photo_view.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:qr_flutter/qr_flutter.dart'; import 'package:qr_flutter/qr_flutter.dart';
import 'package:tablet_app/Components/Carousel/carousel_slider.dart' as cs;
import 'package:tablet_app/Components/loading_common.dart'; import 'package:tablet_app/Components/loading_common.dart';
import 'package:tablet_app/Components/show_element_for_resource.dart'; import 'package:tablet_app/Components/show_element_for_resource.dart';
import 'package:tablet_app/Helpers/ImageCustomProvider.dart'; import 'package:tablet_app/Helpers/ImageCustomProvider.dart';
@ -29,12 +29,12 @@ class MarkerViewWidget extends StatefulWidget {
} }
class _MarkerInfoWidget extends State<MarkerViewWidget> { class _MarkerInfoWidget extends State<MarkerViewWidget> {
CarouselController? sliderController; cs.CarouselController? sliderController;
ValueNotifier<int> currentIndex = ValueNotifier<int>(1); ValueNotifier<int> currentIndex = ValueNotifier<int>(1);
@override @override
void initState() { void initState() {
sliderController = CarouselController(); sliderController = cs.CarouselController();
super.initState(); super.initState();
} }
@ -53,6 +53,8 @@ class _MarkerInfoWidget extends State<MarkerViewWidget> {
var language = tabletAppContext.language; var language = tabletAppContext.language;
GeoPointDTO? selectedPoint = mapContext.getSelectedPoint() as GeoPointDTO?; GeoPointDTO? selectedPoint = mapContext.getSelectedPoint() as GeoPointDTO?;
var isPointPrice = selectedPoint != null && 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;
Color primaryColor = new Color(int.parse(tabletAppContext.configuration!.primaryColor!.split('(0x')[1].split(')')[0], radix: 16)); 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); Size sizeMarker = Size(size.width * 0.9, size.height * 0.8);
@ -163,8 +165,10 @@ class _MarkerInfoWidget extends State<MarkerViewWidget> {
children: [ children: [
Padding( Padding(
padding: const EdgeInsets.only(left: 15), padding: const EdgeInsets.only(left: 15),
child: Container( child: Column(
height: size.height * 0.7, children: [
Container(
height: isPointPrice ? size.height * 0.45 : size.height * 0.7,
width: size.width * 0.38, width: size.width * 0.38,
decoration: BoxDecoration( decoration: BoxDecoration(
color: kBackgroundLight, color: kBackgroundLight,
@ -197,6 +201,46 @@ class _MarkerInfoWidget extends State<MarkerViewWidget> {
), ),
), ),
), ),
if(isPointPrice)
Container(
height: size.height * 0.25,
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.center,
//mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Center(child: Padding(
padding: const EdgeInsets.all(5.0),
child: Icon(Icons.price_change_outlined, color: primaryColor, size: 25),
)),
HtmlWidget(
selectedPoint.prices!.firstWhere((d) => d.language == language).value!+"sdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsd sdkljsdkj sdklj sldkj klsdj klsdj klsd",
customStylesBuilder: (element) {
return {'text-align': 'left', 'font-family': "Roboto"};
},
textStyle: TextStyle(fontSize: kDescriptionSize),
),
],
),
),
),
),
),
),
],
),
), ),
SizedBox( SizedBox(
width: size.width * 0.32, width: size.width * 0.32,
@ -209,10 +253,10 @@ class _MarkerInfoWidget extends State<MarkerViewWidget> {
Container( Container(
//color: Colors.green, //color: Colors.green,
height: size.height * 0.35, height: size.height * 0.35,
child: CarouselSlider( child: cs.CarouselSlider(
carouselController: sliderController, carouselController: sliderController,
options: CarouselOptions( options: cs.CarouselOptions(
onPageChanged: (int index, CarouselPageChangedReason reason) { onPageChanged: (int index, cs.CarouselPageChangedReason reason) {
currentIndex.value = index + 1; currentIndex.value = index + 1;
}, },
height: size.height *0.33, height: size.height *0.33,
@ -238,16 +282,6 @@ class _MarkerInfoWidget extends State<MarkerViewWidget> {
padding: const EdgeInsets.only(top: 10.0), padding: const EdgeInsets.only(top: 10.0),
child: Column( child: Column(
children: [ 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( 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, mainAxisAlignment: MainAxisAlignment.start,
children: [ children: [

View File

@ -98,7 +98,7 @@ class _MenuView extends State<MenuView> {
Align( Align(
alignment: Alignment.centerRight, alignment: Alignment.centerRight,
child: HtmlWidget( child: HtmlWidget(
menuDTO.sections![index].title!.firstWhere((translation) => translation.language == appContext.getContext().language).value!, menuDTO.sections![index].title!.where((translation) => translation.language == appContext.getContext().language).firstOrNull?.value ?? "",
customStylesBuilder: (element) { customStylesBuilder: (element) {
return {'text-align': 'right', 'font-family': "Roboto"}; return {'text-align': 'right', 'font-family': "Roboto"};
}, },
@ -142,7 +142,7 @@ class _MenuView extends State<MenuView> {
), ),
child: Center( child: Center(
child: HtmlWidget( child: HtmlWidget(
menuDTO.sections![index].title!.firstWhere((translation) => translation.language == appContext.getContext().language).value ?? "", menuDTO.sections![index].title!.where((translation) => translation.language == appContext.getContext().language).firstOrNull?.value ?? "",
customStylesBuilder: (element) { customStylesBuilder: (element) {
return {'text-align': 'center', 'font-family': "Roboto"}; return {'text-align': 'center', 'font-family': "Roboto"};
}, },

View File

@ -47,7 +47,7 @@ class _PuzzleView extends State<PuzzleView> {
TabletAppContext tabletAppContext = appContext.getContext(); TabletAppContext tabletAppContext = appContext.getContext();
print(puzzleDTO.messageDebut); print(puzzleDTO.messageDebut);
TranslationAndResourceDTO? messageDebut = puzzleDTO.messageDebut != null && puzzleDTO.messageDebut!.length > 0 ? puzzleDTO.messageDebut!.firstWhere((message) => message.language!.toUpperCase() == tabletAppContext.language!.toUpperCase()) : null; TranslationAndResourceDTO? messageDebut = puzzleDTO.messageDebut != null && puzzleDTO.messageDebut!.length > 0 ? puzzleDTO.messageDebut!.where((message) => message.language!.toUpperCase() == tabletAppContext.language!.toUpperCase()).firstOrNull : null;
if(messageDebut != null) { if(messageDebut != null) {
showMessage(messageDebut, appContext, context, size); showMessage(messageDebut, appContext, context, size);
@ -191,7 +191,7 @@ class _PuzzleView extends State<PuzzleView> {
Size size = MediaQuery.of(context).size; Size size = MediaQuery.of(context).size;
final appContext = Provider.of<AppContext>(context, listen: false); final appContext = Provider.of<AppContext>(context, listen: false);
TabletAppContext tabletAppContext = appContext.getContext(); TabletAppContext tabletAppContext = appContext.getContext();
TranslationAndResourceDTO? messageFin = puzzleDTO.messageFin != null && puzzleDTO.messageFin!.length > 0 ? puzzleDTO.messageFin!.firstWhere((message) => message.language!.toUpperCase() == tabletAppContext.language!.toUpperCase()) : null; TranslationAndResourceDTO? messageFin = puzzleDTO.messageFin != null && puzzleDTO.messageFin!.length > 0 ? puzzleDTO.messageFin!.where((message) => message.language!.toUpperCase() == tabletAppContext.language!.toUpperCase()).firstOrNull : null;
if(messageFin != null) { if(messageFin != null) {
showMessage(messageFin, appContext, context, size); showMessage(messageFin, appContext, context, size);

View File

@ -1,7 +1,6 @@
import 'dart:convert'; import 'dart:convert';
import 'dart:developer'; import 'dart:developer';
import 'package:cached_network_image/cached_network_image.dart'; import 'package:cached_network_image/cached_network_image.dart';
import 'package:carousel_slider/carousel_slider.dart';
import 'package:confetti/confetti.dart'; import 'package:confetti/confetti.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
@ -13,6 +12,7 @@ import 'package:manager_api/api.dart';
import 'package:photo_view/photo_view.dart'; import 'package:photo_view/photo_view.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:tablet_app/Components/Buttons/rounded_button.dart'; import 'package:tablet_app/Components/Buttons/rounded_button.dart';
import 'package:tablet_app/Components/Carousel/carousel_slider.dart' as cs;
import 'package:tablet_app/Components/show_element_for_resource.dart'; import 'package:tablet_app/Components/show_element_for_resource.dart';
import 'package:tablet_app/Helpers/ImageCustomProvider.dart'; import 'package:tablet_app/Helpers/ImageCustomProvider.dart';
import 'package:tablet_app/Helpers/translationHelper.dart'; import 'package:tablet_app/Helpers/translationHelper.dart';
@ -39,7 +39,7 @@ class _QuizzView extends State<QuizzView> {
ConfettiController? _controllerCenter; ConfettiController? _controllerCenter;
QuizzDTO quizzDTO = QuizzDTO(); QuizzDTO quizzDTO = QuizzDTO();
List<QuestionSubDTO> _questionsSubDTO = <QuestionSubDTO>[]; List<QuestionSubDTO> _questionsSubDTO = <QuestionSubDTO>[];
CarouselController? sliderController; cs.CarouselController? sliderController;
int currentIndex = 1; int currentIndex = 1;
bool showResult = false; bool showResult = false;
bool showResponses = false; bool showResponses = false;
@ -50,7 +50,7 @@ class _QuizzView extends State<QuizzView> {
_controllerCenter = ConfettiController(duration: const Duration(seconds: 10)); _controllerCenter = ConfettiController(duration: const Duration(seconds: 10));
sliderController = CarouselController(); sliderController = cs.CarouselController();
quizzDTO = QuizzDTO.fromJson(jsonDecode(widget.section!.data!))!; quizzDTO = QuizzDTO.fromJson(jsonDecode(widget.section!.data!))!;
@ -264,10 +264,10 @@ class _QuizzView extends State<QuizzView> {
mainAxisAlignment: MainAxisAlignment.spaceEvenly, mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [ children: [
if(_questionsSubDTO.length > 0) if(_questionsSubDTO.length > 0)
CarouselSlider( cs.CarouselSlider(
carouselController: sliderController, carouselController: sliderController,
options: CarouselOptions( options: cs.CarouselOptions(
onPageChanged: (int index, CarouselPageChangedReason reason) { onPageChanged: (int index, cs.CarouselPageChangedReason reason) {
setState(() { setState(() {
currentIndex = index + 1; currentIndex = index + 1;
}); });
@ -338,7 +338,7 @@ class _QuizzView extends State<QuizzView> {
//height: size.height * 0.2, //height: size.height * 0.2,
child: Row( child: Row(
children: [ children: [
if(i.label!.firstWhere((translation) => translation.language == appContext.getContext().language).resourceId != null) if(i.label!.where((translation) => translation.language == appContext.getContext().language).firstOrNull?.resourceId != null)
Container( Container(
//height: size.height * 0.2, //height: size.height * 0.2,
//width: size.width * 0.25, //width: size.width * 0.25,
@ -355,11 +355,11 @@ class _QuizzView extends State<QuizzView> {
SingleChildScrollView( SingleChildScrollView(
child: Container( child: Container(
//color: Colors.green, //color: Colors.green,
width: i.label!.firstWhere((translation) => translation.language == appContext.getContext().language).resourceId == null ? size.width * 0.65 : size.width * 0.5, width: i.label!.where((translation) => translation.language == appContext.getContext().language).firstOrNull?.resourceId == null ? size.width * 0.65 : size.width * 0.5,
child: Padding( child: Padding(
padding: const EdgeInsets.all(10.0), padding: const EdgeInsets.all(10.0),
child: HtmlWidget( child: HtmlWidget(
i.label!.firstWhere((translation) => translation.language == appContext.getContext().language).value != null ? i.label!.firstWhere((translation) => translation.language == appContext.getContext().language).value! : "", i.label!.where((translation) => translation.language == appContext.getContext().language).firstOrNull?.value != null ? i.label!.firstWhere((translation) => translation.language == appContext.getContext().language).value! : "",
textStyle: TextStyle(fontSize: kIsWeb ? kWebDescriptionSize : kDescriptionSize), textStyle: TextStyle(fontSize: kIsWeb ? kWebDescriptionSize : kDescriptionSize),
customStylesBuilder: (element) { customStylesBuilder: (element) {
return {'text-align': 'center', 'font-family': "Roboto"}; return {'text-align': 'center', 'font-family': "Roboto"};
@ -416,9 +416,9 @@ class _QuizzView extends State<QuizzView> {
child: Container( child: Container(
alignment: Alignment.center, alignment: Alignment.center,
child: Row(// just to use if else child: Row(// just to use if else
mainAxisAlignment: i.responsesSubDTO![index].label!.firstWhere((translation) => translation.language == appContext.getContext().language).resourceId == null ? MainAxisAlignment.center : MainAxisAlignment.start, mainAxisAlignment: i.responsesSubDTO![index].label!.where((translation) => translation.language == appContext.getContext().language).firstOrNull?.resourceId == null ? MainAxisAlignment.center : MainAxisAlignment.start,
children: [ children: [
if(i.responsesSubDTO![index].label!.firstWhere((translation) => translation.language == appContext.getContext().language).resourceId != null) if(i.responsesSubDTO![index].label!.where((translation) => translation.language == appContext.getContext().language).firstOrNull?.resourceId != null)
Container( Container(
//height: size.height * 0.2, //height: size.height * 0.2,
//width: size.width * 0.25, //width: size.width * 0.25,
@ -434,10 +434,10 @@ class _QuizzView extends State<QuizzView> {
), ),
SingleChildScrollView( SingleChildScrollView(
child: Container( child: Container(
width: i.responsesSubDTO![index].label!.firstWhere((translation) => translation.language == appContext.getContext().language).resourceId == null ? size.width * 0.3 : size.width * 0.13, width: i.responsesSubDTO![index].label!.where((translation) => translation.language == appContext.getContext().language).firstOrNull?.resourceId == null ? size.width * 0.3 : size.width * 0.13,
//color: Colors.yellow, //color: Colors.yellow,
child: HtmlWidget( child: HtmlWidget(
i.responsesSubDTO![index].label!.firstWhere((translation) => translation.language == appContext.getContext().language).value != null ? i.responsesSubDTO![index].label!.firstWhere((translation) => translation.language == appContext.getContext().language).value! : "", i.responsesSubDTO![index].label!.where((translation) => translation.language == appContext.getContext().language).firstOrNull?.value != null ? i.responsesSubDTO![index].label!.firstWhere((translation) => translation.language == appContext.getContext().language).value! : "",
textStyle: TextStyle(fontSize: kIsWeb ? kWebDescriptionSize : kDescriptionSize, color: i.chosen == index ? Colors.white : Colors.black), textStyle: TextStyle(fontSize: kIsWeb ? kWebDescriptionSize : kDescriptionSize, color: i.chosen == index ? Colors.white : Colors.black),
customStylesBuilder: (element) { customStylesBuilder: (element) {
return {'text-align': 'center', 'font-family': "Roboto"}; return {'text-align': 'center', 'font-family': "Roboto"};

View File

@ -1,13 +1,13 @@
import 'dart:convert'; import 'dart:convert';
import 'dart:developer'; import 'dart:developer';
import 'package:cached_network_image/cached_network_image.dart'; import 'package:cached_network_image/cached_network_image.dart';
import 'package:carousel_slider/carousel_slider.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_widget_from_html/flutter_widget_from_html.dart'; import 'package:flutter_widget_from_html/flutter_widget_from_html.dart';
import 'package:manager_api/api.dart'; import 'package:manager_api/api.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:tablet_app/Components/Carousel/carousel_slider.dart' as cs;
import 'package:tablet_app/Helpers/ImageCustomProvider.dart'; import 'package:tablet_app/Helpers/ImageCustomProvider.dart';
import 'package:tablet_app/Models/ResponseSubDTO.dart'; import 'package:tablet_app/Models/ResponseSubDTO.dart';
import 'package:tablet_app/Models/tabletContext.dart'; import 'package:tablet_app/Models/tabletContext.dart';
@ -26,13 +26,13 @@ class ShowReponsesWidget extends StatefulWidget {
class _ShowReponsesWidget extends State<ShowReponsesWidget> { class _ShowReponsesWidget extends State<ShowReponsesWidget> {
List<QuestionSubDTO> _questionsSubDTO = <QuestionSubDTO>[]; List<QuestionSubDTO> _questionsSubDTO = <QuestionSubDTO>[];
CarouselController? sliderController; cs.CarouselController? sliderController;
int currentIndex = 1; int currentIndex = 1;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
sliderController = CarouselController(); sliderController = cs.CarouselController();
_questionsSubDTO = widget.questionsSubDTO!; _questionsSubDTO = widget.questionsSubDTO!;
} }
@ -56,10 +56,10 @@ class _ShowReponsesWidget extends State<ShowReponsesWidget> {
return Stack( return Stack(
children: [ children: [
if(_questionsSubDTO != null && _questionsSubDTO.length > 0) if(_questionsSubDTO != null && _questionsSubDTO.length > 0)
CarouselSlider( cs.CarouselSlider(
carouselController: sliderController, carouselController: sliderController,
options: CarouselOptions( options: cs.CarouselOptions(
onPageChanged: (int index, CarouselPageChangedReason reason) { onPageChanged: (int index, cs.CarouselPageChangedReason reason) {
setState(() { setState(() {
currentIndex = index + 1; currentIndex = index + 1;
}); });

View File

@ -1,7 +1,6 @@
import 'dart:convert'; import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'package:cached_network_image/cached_network_image.dart'; import 'package:cached_network_image/cached_network_image.dart';
import 'package:carousel_slider/carousel_slider.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -9,6 +8,7 @@ import 'package:flutter_widget_from_html/flutter_widget_from_html.dart';
import 'package:manager_api/api.dart'; import 'package:manager_api/api.dart';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:tablet_app/Components/Carousel/carousel_slider.dart' as cs;
import 'package:tablet_app/Components/show_element_for_resource.dart'; import 'package:tablet_app/Components/show_element_for_resource.dart';
import 'package:tablet_app/Components/video_viewer.dart'; import 'package:tablet_app/Components/video_viewer.dart';
import 'package:tablet_app/Helpers/ImageCustomProvider.dart'; import 'package:tablet_app/Helpers/ImageCustomProvider.dart';
@ -27,14 +27,14 @@ class SliderView extends StatefulWidget {
class _SliderView extends State<SliderView> { class _SliderView extends State<SliderView> {
SliderDTO sliderDTO = SliderDTO(); SliderDTO sliderDTO = SliderDTO();
CarouselController? sliderController; cs.CarouselController? sliderController;
ValueNotifier<int> currentIndex = ValueNotifier<int>(1); ValueNotifier<int> currentIndex = ValueNotifier<int>(1);
late ConfigurationDTO configurationDTO; late ConfigurationDTO configurationDTO;
@override @override
void initState() { void initState() {
sliderController = CarouselController(); sliderController = cs.CarouselController();
sliderDTO = SliderDTO.fromJson(jsonDecode(widget.section!.data!))!; sliderDTO = SliderDTO.fromJson(jsonDecode(widget.section!.data!))!;
sliderDTO.contents!.sort((a, b) => a.order!.compareTo(b.order!)); sliderDTO.contents!.sort((a, b) => a.order!.compareTo(b.order!));
@ -60,10 +60,10 @@ class _SliderView extends State<SliderView> {
return Stack( return Stack(
children: [ children: [
if(sliderDTO.contents != null && sliderDTO.contents!.length > 0) if(sliderDTO.contents != null && sliderDTO.contents!.length > 0)
CarouselSlider( cs.CarouselSlider(
carouselController: sliderController, carouselController: sliderController,
options: CarouselOptions( options: cs.CarouselOptions(
onPageChanged: (int index, CarouselPageChangedReason reason) { onPageChanged: (int index, cs.CarouselPageChangedReason reason) {
currentIndex.value = index + 1; currentIndex.value = index + 1;
}, },
height: MediaQuery.of(context).size.height * 0.8, height: MediaQuery.of(context).size.height * 0.8,
@ -119,7 +119,7 @@ class _SliderView extends State<SliderView> {
child: Padding( child: Padding(
padding: const EdgeInsets.all(15.0), padding: const EdgeInsets.all(15.0),
child: HtmlWidget( child: HtmlWidget(
i.title!.firstWhere((translation) => translation.language == appContext.getContext().language).value != null ? i.title!.firstWhere((translation) => translation.language == appContext.getContext().language).value! : "", i.title!.where((translation) => translation.language == appContext.getContext().language).firstOrNull?.value != null ? i.title!.firstWhere((translation) => translation.language == appContext.getContext().language).value! : "",
textStyle: TextStyle(fontSize: kIsWeb ? kWebTitleSize : kTitleSize, color: kBackgroundLight), textStyle: TextStyle(fontSize: kIsWeb ? kWebTitleSize : kTitleSize, color: kBackgroundLight),
), ),
) )
@ -151,7 +151,7 @@ class _SliderView extends State<SliderView> {
child: Padding( child: Padding(
padding: const EdgeInsets.all(15.0), padding: const EdgeInsets.all(15.0),
child: HtmlWidget( child: HtmlWidget(
i.description!.firstWhere((translation) => translation.language == appContext.getContext().language).value != null ? i.description!.firstWhere((translation) => translation.language == appContext.getContext().language).value! : "", i.description!.where((translation) => translation.language == appContext.getContext().language).firstOrNull?.value != null ? i.description!.firstWhere((translation) => translation.language == appContext.getContext().language).value! : "",
textStyle: TextStyle(fontSize: kIsWeb ? kWebDescriptionSize : kDescriptionSize), textStyle: TextStyle(fontSize: kIsWeb ? kWebDescriptionSize : kDescriptionSize),
customStylesBuilder: (element) { customStylesBuilder: (element) {
return {'text-align': 'center', 'font-family': "Roboto"}; return {'text-align': 'center', 'font-family': "Roboto"};

View File

@ -44,8 +44,8 @@ void main() async {
print(localContext.instanceId); print(localContext.instanceId);
// Get config from manager // Get config from manager
DeviceDetailDTO? device = await localContext.clientAPI!.deviceApi!.deviceGetDetail(localContext.deviceId!); DeviceDetailDTO? device = await localContext.clientAPI!.deviceApi!.deviceGetDetail(localContext.deviceId!);
localContext.configuration!.id = device!.configurationId; localContext.configuration!.id = device!.configurationId;//device!.configurationId; //Hardcoded for VisitNamur 65c5f0ee4c030e63ce16bff5 // DEV 65859c77d97d1b93ce301e91
localContext.instanceId = device.instanceId; localContext.instanceId = device.instanceId;// device.instanceId; //Hardcoded for VisitNamur 65c5e576ad331aa079caf0a4 // DEV 63514fd67ed8c735aaa4b8f2
localContext.localPath = localPath; localContext.localPath = localPath;
if (device.configurationId == null) { if (device.configurationId == null) {

View File

@ -6,25 +6,33 @@ import FlutterMacOS
import Foundation import Foundation
import audio_session import audio_session
import device_info_plus
import firebase_core import firebase_core
import firebase_storage import firebase_storage
import flutter_inappwebview_macos
import just_audio import just_audio
import package_info import package_info
import package_info_plus
import path_provider_foundation import path_provider_foundation
import shared_preferences_foundation import shared_preferences_foundation
import sqflite import sqflite
import url_launcher_macos import url_launcher_macos
import wakelock_macos import video_player_avfoundation
import wakelock_plus
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
AudioSessionPlugin.register(with: registry.registrar(forPlugin: "AudioSessionPlugin")) AudioSessionPlugin.register(with: registry.registrar(forPlugin: "AudioSessionPlugin"))
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin")) FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin"))
FLTFirebaseStoragePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseStoragePlugin")) FLTFirebaseStoragePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseStoragePlugin"))
InAppWebViewFlutterPlugin.register(with: registry.registrar(forPlugin: "InAppWebViewFlutterPlugin"))
JustAudioPlugin.register(with: registry.registrar(forPlugin: "JustAudioPlugin")) JustAudioPlugin.register(with: registry.registrar(forPlugin: "JustAudioPlugin"))
FLTPackageInfoPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlugin")) FLTPackageInfoPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlugin"))
FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
WakelockMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockMacosPlugin")) FVPVideoPlayerPlugin.register(with: registry.registrar(forPlugin: "FVPVideoPlayerPlugin"))
WakelockPlusMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockPlusMacosPlugin"))
} }

View File

@ -3,8 +3,8 @@ FLUTTER_ROOT=C:\PROJ\flutter
FLUTTER_APPLICATION_PATH=C:\Users\ThomasFransolet\Documents\Documents\Perso\MuseeDeLaFraise\tablet-app FLUTTER_APPLICATION_PATH=C:\Users\ThomasFransolet\Documents\Documents\Perso\MuseeDeLaFraise\tablet-app
COCOAPODS_PARALLEL_CODE_SIGN=true COCOAPODS_PARALLEL_CODE_SIGN=true
FLUTTER_BUILD_DIR=build FLUTTER_BUILD_DIR=build
FLUTTER_BUILD_NAME=2.0.6 FLUTTER_BUILD_NAME=2.0.7
FLUTTER_BUILD_NUMBER=12 FLUTTER_BUILD_NUMBER=15
DART_OBFUSCATION=false DART_OBFUSCATION=false
TRACK_WIDGET_CREATION=true TRACK_WIDGET_CREATION=true
TREE_SHAKE_ICONS=false TREE_SHAKE_ICONS=false

View File

@ -4,8 +4,8 @@ export "FLUTTER_ROOT=C:\PROJ\flutter"
export "FLUTTER_APPLICATION_PATH=C:\Users\ThomasFransolet\Documents\Documents\Perso\MuseeDeLaFraise\tablet-app" export "FLUTTER_APPLICATION_PATH=C:\Users\ThomasFransolet\Documents\Documents\Perso\MuseeDeLaFraise\tablet-app"
export "COCOAPODS_PARALLEL_CODE_SIGN=true" export "COCOAPODS_PARALLEL_CODE_SIGN=true"
export "FLUTTER_BUILD_DIR=build" export "FLUTTER_BUILD_DIR=build"
export "FLUTTER_BUILD_NAME=2.0.6" export "FLUTTER_BUILD_NAME=2.0.7"
export "FLUTTER_BUILD_NUMBER=12" export "FLUTTER_BUILD_NUMBER=15"
export "DART_OBFUSCATION=false" export "DART_OBFUSCATION=false"
export "TRACK_WIDGET_CREATION=true" export "TRACK_WIDGET_CREATION=true"
export "TREE_SHAKE_ICONS=false" export "TREE_SHAKE_ICONS=false"

View File

@ -28,13 +28,13 @@ dependencies:
sqflite: # Specific mobile and macOS sqflite: # Specific mobile and macOS
webview_flutter: ^4.4.1 # Specific mobile # old : ^3.0.4 webview_flutter: ^4.4.1 # Specific mobile # old : ^3.0.4
google_maps_flutter: ^2.5.3 # Specific mobile google_maps_flutter: ^2.5.3 # Specific mobile
youtube_player_flutter: ^8.1.2 # Specific mobile youtube_player_flutter: ^9.0.1 # Specific mobile
# Specific Web # Specific Web
google_maps_flutter_web: ^0.5.4+3 # Specific WEB google_maps_flutter_web: ^0.5.4+3 # Specific WEB
youtube_player_iframe: ^4.0.4 # Handle mobile and web here => TO TEST youtube_player_iframe: ^5.1.2 # Handle mobile and web here => TO TEST
mapbox_maps_flutter: ^1.0.0 mapbox_maps_flutter: ^2.0.0
ota_update: ^6.0.0 ota_update: ^6.0.0
package_info: ^2.0.2 package_info: ^2.0.2
@ -46,35 +46,35 @@ dependencies:
http: ^1.2.0 http: ^1.2.0
auto_size_text: ^3.0.0 auto_size_text: ^3.0.0
fluttertoast: fluttertoast:
device_info: ^2.0.2 # DISCONTINUED device_info_plus: ^10.1.0
#device_info_plus: ^10.0.1 # chewie version casse couille, retourne à la 1.0.0 qui fout la merde
enum_to_string: ^2.0.1 enum_to_string: ^2.0.1
carousel_slider: ^4.2.1
mqtt_client: ^10.0.0 mqtt_client: ^10.0.0
photo_view: ^0.14.0 photo_view: ^0.15.0
confetti: ^0.7.0 confetti: ^0.7.0
flutter_launcher_icons: ^0.13.1 # All but web flutter_launcher_icons: ^0.13.1 # All but web
#flutter_svg_provider: ^1.0.6 #flutter_svg_provider: ^1.0.6
flutter_widget_from_html: ^0.14.10+1 flutter_widget_from_html: ^0.15.1
flutter_pdfview: ^1.3.2 flutter_pdfview: ^1.3.2
firebase_storage: ^11.7.3 firebase_storage: ^12.0.1
firebase_core: ^2.30.1 firebase_core: ^3.1.0
#video_player: ^2.8.1 video_player: ^2.8.7
cached_video_player: ^2.0.4 #cached_video_player: ^2.0.4
cached_network_image: ^3.3.1 cached_network_image: ^3.3.1
just_audio_cache: ^0.1.2 just_audio_cache: ^0.1.2
path_provider: ^2.1.2 #path_provider: ^2.1.2
permission_handler: ^11.2.0 permission_handler: ^11.2.0
google_fonts: ^6.2.1 google_fonts: ^6.2.1
#animated_tree_view: ^2.2.0 #animated_tree_view: ^2.2.0
generate_tree: ^2.2.2 generate_tree: ^2.2.2
openapi_generator_cli: ^4.13.1 openapi_generator_cli: ^5.0.2
openapi_generator: ^4.13.1 openapi_generator: ^5.0.2
openapi_generator_annotations: ^4.13.1 openapi_generator_annotations: ^5.0.2
# The following adds the Cupertino Icons font to your application. # The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons. # Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.6 cupertino_icons: ^1.0.6
#win32: ^4.1.2
#archive: ^3.6.1
manager_api: manager_api:
path: manager_api path: manager_api
@ -82,7 +82,7 @@ dev_dependencies:
flutter_test: flutter_test:
sdk: flutter sdk: flutter
build_runner: build_runner:
openapi_generator: ^4.13.1 openapi_generator: ^5.0.2
# For information on the generic Dart part of this file, see the # For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec # following page: https://dart.dev/tools/pub/pubspec