mirror of
https://bitbucket.org/FransoletThomas/tablet-app.git
synced 2025-12-06 16:41:19 +00:00
Puzzle (handle cols rows + message) + show element for resource
This commit is contained in:
parent
e67880bc50
commit
cad16a35d3
245
lib/Components/audio_player.dart
Normal file
245
lib/Components/audio_player.dart
Normal file
@ -0,0 +1,245 @@
|
|||||||
|
import 'dart:typed_data';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
import 'package:just_audio/just_audio.dart';
|
||||||
|
import 'package:tablet_app/Models/tabletContext.dart';
|
||||||
|
import 'package:tablet_app/app_context.dart';
|
||||||
|
|
||||||
|
|
||||||
|
class AudioPlayerFloatingContainer extends StatefulWidget {
|
||||||
|
const AudioPlayerFloatingContainer({Key? key, required this.audioBytes, required this.resourceURl, required this.isAuto}) : super(key: key);
|
||||||
|
|
||||||
|
final Uint8List? audioBytes;
|
||||||
|
final String resourceURl;
|
||||||
|
final bool isAuto;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<AudioPlayerFloatingContainer> createState() => _AudioPlayerFloatingContainerState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AudioPlayerFloatingContainerState extends State<AudioPlayerFloatingContainer> {
|
||||||
|
AudioPlayer player = AudioPlayer();
|
||||||
|
late Uint8List audiobytes;
|
||||||
|
bool isplaying = false;
|
||||||
|
bool audioplayed = false;
|
||||||
|
int currentpos = 0;
|
||||||
|
int maxduration = 100;
|
||||||
|
Duration? durationAudio;
|
||||||
|
String currentpostlabel = "00:00";
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
Future.delayed(Duration.zero, () async {
|
||||||
|
if(widget.audioBytes != null) {
|
||||||
|
audiobytes = widget.audioBytes!;
|
||||||
|
}
|
||||||
|
|
||||||
|
player.durationStream.listen((Duration? d) { //get the duration of audio
|
||||||
|
if(d != null) {
|
||||||
|
maxduration = d.inSeconds;
|
||||||
|
durationAudio = d;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//player.bufferedPositionStream
|
||||||
|
|
||||||
|
player.positionStream.listen((event) {
|
||||||
|
if(durationAudio != null) {
|
||||||
|
|
||||||
|
currentpos = event.inMilliseconds; //get the current position of playing audio
|
||||||
|
|
||||||
|
//generating the duration label
|
||||||
|
int shours = Duration(milliseconds:durationAudio!.inMilliseconds - currentpos).inHours;
|
||||||
|
int sminutes = Duration(milliseconds:durationAudio!.inMilliseconds - currentpos).inMinutes;
|
||||||
|
int sseconds = Duration(milliseconds:durationAudio!.inMilliseconds - currentpos).inSeconds;
|
||||||
|
|
||||||
|
int rminutes = sminutes - (shours * 60);
|
||||||
|
int rseconds = sseconds - (sminutes * 60 + shours * 60 * 60);
|
||||||
|
|
||||||
|
String minutesToShow = rminutes < 10 ? '0$rminutes': rminutes.toString();
|
||||||
|
String secondsToShow = rseconds < 10 ? '0$rseconds': rseconds.toString();
|
||||||
|
|
||||||
|
currentpostlabel = "$minutesToShow:$secondsToShow";
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
//refresh the UI
|
||||||
|
if(currentpos > player.duration!.inMilliseconds) {
|
||||||
|
print("RESET ALL");
|
||||||
|
player.stop();
|
||||||
|
player.seek(const Duration(seconds: 0));
|
||||||
|
isplaying = false;
|
||||||
|
audioplayed = false;
|
||||||
|
currentpostlabel = "00:00";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*player.onPositionChanged.listen((Duration p){
|
||||||
|
currentpos = p.inMilliseconds; //get the current position of playing audio
|
||||||
|
|
||||||
|
//generating the duration label
|
||||||
|
int shours = Duration(milliseconds:currentpos).inHours;
|
||||||
|
int sminutes = Duration(milliseconds:currentpos).inMinutes;
|
||||||
|
int sseconds = Duration(milliseconds:currentpos).inSeconds;
|
||||||
|
|
||||||
|
int rminutes = sminutes - (shours * 60);
|
||||||
|
int rseconds = sseconds - (sminutes * 60 + shours * 60 * 60);
|
||||||
|
|
||||||
|
String minutesToShow = rminutes < 10 ? '0$rminutes': rminutes.toString();
|
||||||
|
String secondsToShow = rseconds < 10 ? '0$rseconds': rseconds.toString();
|
||||||
|
|
||||||
|
currentpostlabel = "$minutesToShow:$secondsToShow";
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
//refresh the UI
|
||||||
|
});
|
||||||
|
});*/
|
||||||
|
|
||||||
|
if(widget.isAuto) {
|
||||||
|
//player.play(BytesSource(audiobytes));
|
||||||
|
//await player.setAudioSource(LoadedSource(audiobytes));
|
||||||
|
await player.setUrl(widget.resourceURl);
|
||||||
|
player.play();
|
||||||
|
setState(() {
|
||||||
|
isplaying = true;
|
||||||
|
audioplayed = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
player.stop();
|
||||||
|
player.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final appContext = Provider.of<AppContext>(context);
|
||||||
|
TabletAppContext tabletAppContext = appContext.getContext();
|
||||||
|
|
||||||
|
return FloatingActionButton(
|
||||||
|
backgroundColor: new Color(int.parse(tabletAppContext.configuration!.primaryColor!.split('(0x')[1].split(')')[0], radix: 16)).withOpacity(0.7),
|
||||||
|
onPressed: () async {
|
||||||
|
if(!isplaying && !audioplayed){
|
||||||
|
//player.play(BytesSource(audiobytes));
|
||||||
|
await player.setAudioSource(LoadedSource(audiobytes));
|
||||||
|
player.play();
|
||||||
|
setState(() {
|
||||||
|
isplaying = true;
|
||||||
|
audioplayed = true;
|
||||||
|
});
|
||||||
|
}else if(audioplayed && !isplaying){
|
||||||
|
//player.resume();
|
||||||
|
player.play();
|
||||||
|
setState(() {
|
||||||
|
isplaying = true;
|
||||||
|
audioplayed = true;
|
||||||
|
});
|
||||||
|
}else{
|
||||||
|
player.pause();
|
||||||
|
setState(() {
|
||||||
|
isplaying = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: isplaying ? Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
const Icon(Icons.pause),
|
||||||
|
Text(currentpostlabel),
|
||||||
|
],
|
||||||
|
) : audioplayed ? Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
const Icon(Icons.play_arrow),
|
||||||
|
Text(currentpostlabel),
|
||||||
|
],
|
||||||
|
): const Icon(Icons.play_arrow),
|
||||||
|
|
||||||
|
/*Column(
|
||||||
|
children: [
|
||||||
|
//Text(currentpostlabel, style: const TextStyle(fontSize: 25)),
|
||||||
|
Wrap(
|
||||||
|
spacing: 10,
|
||||||
|
children: [
|
||||||
|
ElevatedButton.icon(
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: kSecondColor, // Background color
|
||||||
|
),
|
||||||
|
onPressed: () async {
|
||||||
|
if(!isplaying && !audioplayed){
|
||||||
|
//player.play(BytesSource(audiobytes));
|
||||||
|
await player.setAudioSource(LoadedSource(audiobytes));
|
||||||
|
player.play();
|
||||||
|
setState(() {
|
||||||
|
isplaying = true;
|
||||||
|
audioplayed = true;
|
||||||
|
});
|
||||||
|
}else if(audioplayed && !isplaying){
|
||||||
|
//player.resume();
|
||||||
|
player.play();
|
||||||
|
setState(() {
|
||||||
|
isplaying = true;
|
||||||
|
audioplayed = true;
|
||||||
|
});
|
||||||
|
}else{
|
||||||
|
player.pause();
|
||||||
|
setState(() {
|
||||||
|
isplaying = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
icon: Icon(isplaying?Icons.pause:Icons.play_arrow),
|
||||||
|
//label:Text(isplaying?TranslationHelper.getFromLocale("pause", appContext.getContext()):TranslationHelper.getFromLocale("play", appContext.getContext()))
|
||||||
|
),
|
||||||
|
|
||||||
|
/*ElevatedButton.icon(
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: kSecondColor, // Background color
|
||||||
|
),
|
||||||
|
onPressed: () async {
|
||||||
|
player.stop();
|
||||||
|
player.seek(const Duration(seconds: 0));
|
||||||
|
setState(() {
|
||||||
|
isplaying = false;
|
||||||
|
audioplayed = false;
|
||||||
|
currentpostlabel = "00:00";
|
||||||
|
});
|
||||||
|
},
|
||||||
|
icon: const Icon(Icons.stop),
|
||||||
|
//label: Text(TranslationHelper.getFromLocale("stop", appContext.getContext()))
|
||||||
|
),*/
|
||||||
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),*/
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Feed your own stream of bytes into the player
|
||||||
|
class LoadedSource extends StreamAudioSource {
|
||||||
|
final List<int> bytes;
|
||||||
|
LoadedSource(this.bytes);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<StreamAudioResponse> request([int? start, int? end]) async {
|
||||||
|
start ??= 0;
|
||||||
|
end ??= bytes.length;
|
||||||
|
return StreamAudioResponse(
|
||||||
|
sourceLength: bytes.length,
|
||||||
|
contentLength: end - start,
|
||||||
|
offset: start,
|
||||||
|
stream: Stream.value(bytes.sublist(start, end)),
|
||||||
|
contentType: 'audio/mpeg',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,4 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:tablet_app/Models/tabletContext.dart';
|
||||||
|
import 'package:tablet_app/app_context.dart';
|
||||||
import 'package:tablet_app/constants.dart';
|
import 'package:tablet_app/constants.dart';
|
||||||
|
|
||||||
class LoadingCommon extends StatefulWidget {
|
class LoadingCommon extends StatefulWidget {
|
||||||
@ -28,6 +31,9 @@ class _LoadingCommonState extends State<LoadingCommon> with TickerProviderStateM
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
final appContext = Provider.of<AppContext>(context);
|
||||||
|
TabletAppContext tabletAppContext = appContext.getContext();
|
||||||
|
|
||||||
Size size = MediaQuery.of(context).size;
|
Size size = MediaQuery.of(context).size;
|
||||||
_controller!.forward(from: 0.0);
|
_controller!.forward(from: 0.0);
|
||||||
_controller!.addListener(() {
|
_controller!.addListener(() {
|
||||||
@ -39,9 +45,14 @@ class _LoadingCommonState extends State<LoadingCommon> with TickerProviderStateM
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
return Center(
|
return Center(
|
||||||
child: RotationTransition(
|
child: SizedBox(
|
||||||
turns: Tween(begin: 0.0, end: 3.0).animate(_controller!),
|
height: size.height * 0.1,
|
||||||
child: Icon(Icons.museum_outlined, color: kTestSecondColor, size: size.height*0.1),
|
child: RotationTransition(
|
||||||
|
turns: Tween(begin: 0.0, end: 3.0).animate(_controller!),
|
||||||
|
child: tabletAppContext.configuration != null && tabletAppContext.configuration!.loaderImageUrl != null ?
|
||||||
|
Image.network(tabletAppContext.configuration!.loaderImageUrl!)
|
||||||
|
: Icon(Icons.museum_outlined, color: kTestSecondColor, size: size.height*0.1),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
100
lib/Components/show_element_for_resource.dart
Normal file
100
lib/Components/show_element_for_resource.dart
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:http/http.dart' as http;
|
||||||
|
import 'package:manager_api/api.dart';
|
||||||
|
import 'package:tablet_app/Components/audio_player.dart';
|
||||||
|
import 'package:tablet_app/Components/video_viewer.dart';
|
||||||
|
import 'package:tablet_app/Components/video_viewer_youtube.dart';
|
||||||
|
import 'package:tablet_app/Models/tabletContext.dart';
|
||||||
|
import 'package:tablet_app/app_context.dart';
|
||||||
|
|
||||||
|
showElementForResource(ResourceDTO resourceDTO, AppContext appContext) {
|
||||||
|
TabletAppContext tabletAppContext = appContext.getContext();
|
||||||
|
Color primaryColor = new Color(int.parse(tabletAppContext.configuration!.primaryColor!.split('(0x')[1].split(')')[0], radix: 16));
|
||||||
|
|
||||||
|
switch(resourceDTO.type) {
|
||||||
|
case ResourceType.Image:
|
||||||
|
return Image.network(
|
||||||
|
resourceDTO.url!,
|
||||||
|
fit:BoxFit.fill,
|
||||||
|
loadingBuilder: (BuildContext context, Widget child,
|
||||||
|
ImageChunkEvent? loadingProgress) {
|
||||||
|
if (loadingProgress == null) {
|
||||||
|
return child;
|
||||||
|
}
|
||||||
|
return Center(
|
||||||
|
child: CircularProgressIndicator(
|
||||||
|
color: primaryColor,
|
||||||
|
value: loadingProgress.expectedTotalBytes != null
|
||||||
|
? loadingProgress.cumulativeBytesLoaded /
|
||||||
|
loadingProgress.expectedTotalBytes!
|
||||||
|
: null,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case ResourceType.ImageUrl:
|
||||||
|
return Image.network(
|
||||||
|
resourceDTO.url!,
|
||||||
|
fit:BoxFit.fill,
|
||||||
|
loadingBuilder: (BuildContext context, Widget child,
|
||||||
|
ImageChunkEvent? loadingProgress) {
|
||||||
|
if (loadingProgress == null) {
|
||||||
|
return child;
|
||||||
|
}
|
||||||
|
return Center(
|
||||||
|
child: CircularProgressIndicator(
|
||||||
|
color: primaryColor,
|
||||||
|
value: loadingProgress.expectedTotalBytes != null
|
||||||
|
? loadingProgress.cumulativeBytesLoaded /
|
||||||
|
loadingProgress.expectedTotalBytes!
|
||||||
|
: null,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
case ResourceType.Audio:
|
||||||
|
return AudioPlayerFloatingContainer(audioBytes: null, resourceURl: resourceDTO.url!, isAuto: true);
|
||||||
|
/*return FutureBuilder(
|
||||||
|
future: getAudio(resourceDTO.url, appContext),
|
||||||
|
builder: (context, AsyncSnapshot<dynamic> snapshot) {
|
||||||
|
Size size = MediaQuery.of(context).size;
|
||||||
|
if (snapshot.connectionState == ConnectionState.done) {
|
||||||
|
var audioBytes;
|
||||||
|
if(snapshot.data != null) {
|
||||||
|
print("snapshot.data");
|
||||||
|
print(snapshot.data);
|
||||||
|
audioBytes = snapshot.data;
|
||||||
|
//this.player.playBytes(audiobytes);
|
||||||
|
}
|
||||||
|
return AudioPlayerFloatingContainer(audioBytes: audioBytes, resourceURl: resourceDTO.url, isAuto: true);
|
||||||
|
} else if (snapshot.connectionState == ConnectionState.none) {
|
||||||
|
return Text("No data");
|
||||||
|
} else {
|
||||||
|
return Center(
|
||||||
|
child: Container(
|
||||||
|
//height: size.height * 0.2,
|
||||||
|
width: size.width * 0.2,
|
||||||
|
child: LoadingCommon()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);*/
|
||||||
|
case ResourceType.Video:
|
||||||
|
if(resourceDTO.url == null) {
|
||||||
|
return Center(child: Text("Error loading video"));
|
||||||
|
} else {
|
||||||
|
return VideoViewer(videoUrl: resourceDTO.url!);
|
||||||
|
}
|
||||||
|
case ResourceType.VideoUrl:
|
||||||
|
if(resourceDTO.url == null) {
|
||||||
|
return Center(child: Text("Error loading video"));
|
||||||
|
} else {
|
||||||
|
return VideoViewerYoutube(videoUrl: resourceDTO.url!);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
93
lib/Components/video_viewer_youtube.dart
Normal file
93
lib/Components/video_viewer_youtube.dart
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:manager_api/api.dart';
|
||||||
|
import 'package:tablet_app/constants.dart';
|
||||||
|
import 'package:youtube_player_iframe/youtube_player_iframe.dart' as iframe;
|
||||||
|
import 'package:youtube_player_flutter/youtube_player_flutter.dart';
|
||||||
|
|
||||||
|
class VideoViewerYoutube extends StatefulWidget {
|
||||||
|
final String videoUrl;
|
||||||
|
VideoViewerYoutube({required this.videoUrl});
|
||||||
|
|
||||||
|
@override
|
||||||
|
_VideoViewerYoutube createState() => _VideoViewerYoutube();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _VideoViewerYoutube extends State<VideoViewerYoutube> {
|
||||||
|
iframe.YoutubePlayer? _videoViewWeb;
|
||||||
|
YoutubePlayer? _videoView;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
String? videoId;
|
||||||
|
if (widget.videoUrl.length > 0 ) {
|
||||||
|
videoId = YoutubePlayer.convertUrlToId(widget.videoUrl);
|
||||||
|
|
||||||
|
if (kIsWeb) {
|
||||||
|
final _controllerWeb = iframe.YoutubePlayerController(
|
||||||
|
params: iframe.YoutubePlayerParams(
|
||||||
|
mute: false,
|
||||||
|
showControls: true,
|
||||||
|
showFullscreenButton: false,
|
||||||
|
loop: true,
|
||||||
|
showVideoAnnotations: false,
|
||||||
|
strictRelatedVideos: false,
|
||||||
|
enableKeyboard: false,
|
||||||
|
enableCaption: false,
|
||||||
|
pointerEvents: iframe.PointerEvents.auto
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
_controllerWeb.loadVideo(widget.videoUrl);
|
||||||
|
|
||||||
|
_videoViewWeb = iframe.YoutubePlayer(
|
||||||
|
controller: _controllerWeb,
|
||||||
|
//showVideoProgressIndicator: false,
|
||||||
|
/*progressIndicatorColor: Colors.amber,
|
||||||
|
progressColors: ProgressBarColors(
|
||||||
|
playedColor: Colors.amber,
|
||||||
|
handleColor: Colors.amberAccent,
|
||||||
|
),*/
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
videoId = YoutubePlayer.convertUrlToId(widget.videoUrl);
|
||||||
|
YoutubePlayerController _controller = YoutubePlayerController(
|
||||||
|
initialVideoId: videoId!,
|
||||||
|
flags: YoutubePlayerFlags(
|
||||||
|
autoPlay: true,
|
||||||
|
controlsVisibleAtStart: false,
|
||||||
|
loop: true,
|
||||||
|
hideControls: false,
|
||||||
|
hideThumbnail: false,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
_videoView = YoutubePlayer(
|
||||||
|
controller: _controller,
|
||||||
|
//showVideoProgressIndicator: false,
|
||||||
|
progressIndicatorColor: Colors.amber,
|
||||||
|
progressColors: ProgressBarColors(
|
||||||
|
playedColor: Colors.amber,
|
||||||
|
handleColor: Colors.amberAccent,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_videoView = null;
|
||||||
|
_videoViewWeb = null;
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) => widget.videoUrl.length > 0 ?
|
||||||
|
(kIsWeb ? _videoViewWeb! : _videoView!):
|
||||||
|
Center(child: Text("La vidéo ne peut pas être affichée, l'url est incorrecte", style: new TextStyle(fontSize: kNoneInfoOrIncorrect)));
|
||||||
|
}
|
||||||
@ -1,7 +1,7 @@
|
|||||||
import 'package:manager_api/api.dart';
|
import 'package:manager_api/api.dart';
|
||||||
|
|
||||||
class ResponseSubDTO {
|
class ResponseSubDTO {
|
||||||
List<TranslationDTO>? label;
|
List<TranslationAndResourceDTO>? label;
|
||||||
bool? isGood;
|
bool? isGood;
|
||||||
int? order;
|
int? order;
|
||||||
|
|
||||||
@ -25,14 +25,14 @@ class ResponseSubDTO {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class QuestionSubDTO {
|
class QuestionSubDTO {
|
||||||
List<TranslationDTO>? label;
|
List<TranslationAndResourceDTO>? label;
|
||||||
List<ResponseSubDTO>? responsesSubDTO;
|
List<ResponseSubDTO>? responsesSubDTO;
|
||||||
int? chosen;
|
int? chosen;
|
||||||
String? resourceId;
|
String? resourceId;
|
||||||
String? source_;
|
String? resourceUrl;
|
||||||
int? order;
|
int? order;
|
||||||
|
|
||||||
QuestionSubDTO({this.label, this.responsesSubDTO, this.chosen, this.resourceId, this.source_, this.order});
|
QuestionSubDTO({this.label, this.responsesSubDTO, this.chosen, this.resourceId, this.resourceUrl, this.order});
|
||||||
|
|
||||||
List<QuestionSubDTO> fromJSON(List<QuestionDTO> questionsDTO) {
|
List<QuestionSubDTO> fromJSON(List<QuestionDTO> questionsDTO) {
|
||||||
List<QuestionSubDTO> questionSubDTO = <QuestionSubDTO>[];
|
List<QuestionSubDTO> questionSubDTO = <QuestionSubDTO>[];
|
||||||
@ -42,8 +42,8 @@ class QuestionSubDTO {
|
|||||||
chosen: null,
|
chosen: null,
|
||||||
label: questionDTO.label,
|
label: questionDTO.label,
|
||||||
responsesSubDTO: ResponseSubDTO().fromJSON(questionDTO.responses!),
|
responsesSubDTO: ResponseSubDTO().fromJSON(questionDTO.responses!),
|
||||||
resourceId: questionDTO.resourceId,
|
resourceId: questionDTO.imageBackgroundResourceId,
|
||||||
source_: questionDTO.source_,
|
resourceUrl: questionDTO.imageBackgroundResourceUrl,
|
||||||
order: questionDTO.order,
|
order: questionDTO.order,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,18 +4,18 @@ class MapMarker {
|
|||||||
int? id;
|
int? id;
|
||||||
String? title;
|
String? title;
|
||||||
String? description;
|
String? description;
|
||||||
List<ImageGeoPoint>? images;
|
List<ContentGeoPoint>? contents;
|
||||||
String? latitude;
|
String? latitude;
|
||||||
String? longitude;
|
String? longitude;
|
||||||
|
|
||||||
MapMarker({this.id, this.title, this.description, this.images, this.latitude, this.longitude});
|
MapMarker({this.id, this.title, this.description, this.contents, this.latitude, this.longitude});
|
||||||
|
|
||||||
factory MapMarker.fromJson(Map<String, dynamic> json) {
|
factory MapMarker.fromJson(Map<String, dynamic> json) {
|
||||||
return new MapMarker(
|
return new MapMarker(
|
||||||
id: json['id'] as int,
|
id: json['id'] as int,
|
||||||
title: json['title'] as String,
|
title: json['title'] as String,
|
||||||
description: json['description'] as String,
|
description: json['description'] as String,
|
||||||
images: json['image'] as List<ImageGeoPoint>,
|
contents: json['contents'] as List<ContentGeoPoint>,
|
||||||
latitude: json['latitude'] as String,
|
latitude: json['latitude'] as String,
|
||||||
longitude: json['longitude'] as String,
|
longitude: json['longitude'] as String,
|
||||||
);
|
);
|
||||||
@ -23,6 +23,6 @@ class MapMarker {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'MapMarker{id: $id, title: $title, description: $description, images: $images, latitude: $latitude, longitude: $longitude}';
|
return 'MapMarker{id: $id, title: $title, description: $description, contents: $contents, latitude: $latitude, longitude: $longitude}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -16,6 +16,7 @@ class TabletAppContext with ChangeNotifier{
|
|||||||
String? language;
|
String? language;
|
||||||
String? deviceId;
|
String? deviceId;
|
||||||
String? instanceId;
|
String? instanceId;
|
||||||
|
Size? puzzleSize;
|
||||||
|
|
||||||
TabletAppContext({this.id, this.deviceId, this.host, this.configuration, this.language, this.instanceId, this.clientAPI});
|
TabletAppContext({this.id, this.deviceId, this.host, this.configuration, this.language, this.instanceId, this.clientAPI});
|
||||||
|
|
||||||
|
|||||||
45
lib/Screens/Agenda/agenda_view.dart
Normal file
45
lib/Screens/Agenda/agenda_view.dart
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:io';
|
||||||
|
//import 'dart:html';
|
||||||
|
import 'dart:ui' as ui;
|
||||||
|
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:manager_api/api.dart';
|
||||||
|
import 'package:path_provider/path_provider.dart';
|
||||||
|
import 'package:tablet_app/Components/loading_common.dart';
|
||||||
|
|
||||||
|
|
||||||
|
class AgendaView extends StatefulWidget {
|
||||||
|
final SectionDTO? section;
|
||||||
|
AgendaView({this.section});
|
||||||
|
|
||||||
|
@override
|
||||||
|
_AgendaView createState() => _AgendaView();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AgendaView extends State<AgendaView> {
|
||||||
|
AgendaDTO agendaDTO = AgendaDTO();
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
print(widget.section!.data);
|
||||||
|
agendaDTO = AgendaDTO.fromJson(jsonDecode(widget.section!.data!))!;
|
||||||
|
print(agendaDTO);
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return new Center(
|
||||||
|
child: Text("TODO Agenda"),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} //_webView
|
||||||
46
lib/Screens/Article/article_view.dart
Normal file
46
lib/Screens/Article/article_view.dart
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:io';
|
||||||
|
//import 'dart:html';
|
||||||
|
import 'dart:ui' as ui;
|
||||||
|
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:manager_api/api.dart';
|
||||||
|
import 'package:path_provider/path_provider.dart';
|
||||||
|
import 'package:tablet_app/Components/loading_common.dart';
|
||||||
|
|
||||||
|
|
||||||
|
class ArticleView extends StatefulWidget {
|
||||||
|
final SectionDTO? section;
|
||||||
|
ArticleView({this.section});
|
||||||
|
|
||||||
|
@override
|
||||||
|
_ArticleView createState() => _ArticleView();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ArticleView extends State<ArticleView> {
|
||||||
|
AgendaDTO agendaDTO = AgendaDTO();
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
print(widget.section!.data);
|
||||||
|
agendaDTO = AgendaDTO.fromJson(jsonDecode(widget.section!.data!))!;
|
||||||
|
print(agendaDTO);
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
//_webView = null;
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return new Center(
|
||||||
|
child: Text("TODO Agenda"),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} //_webView
|
||||||
@ -84,30 +84,33 @@ class _LanguageSelection extends State<LanguageSelection> with TickerProviderSta
|
|||||||
left: _leftLanguage,
|
left: _leftLanguage,
|
||||||
right: _rightLanguage,
|
right: _rightLanguage,
|
||||||
bottom: _bottomLanguage,
|
bottom: _bottomLanguage,
|
||||||
child: ListView(
|
child: Padding(
|
||||||
children: [
|
padding: const EdgeInsets.only(top: 25.0),
|
||||||
if(minimized) ... [
|
child: ListView(
|
||||||
for(var language in languagesEnable!.where((element) => element.toUpperCase() != selectedLanguage ))
|
children: [
|
||||||
InkWell(
|
if(minimized) ... [
|
||||||
onTap: () {
|
for(var language in languagesEnable!.where((element) => element.toUpperCase() != selectedLanguage ))
|
||||||
setState(() {
|
InkWell(
|
||||||
TabletAppContext tabletAppContext = appContext.getContext();
|
onTap: () {
|
||||||
tabletAppContext.language = language;
|
setState(() {
|
||||||
appContext.setContext(tabletAppContext);
|
TabletAppContext tabletAppContext = appContext.getContext();
|
||||||
minimizedAnimation(size);
|
tabletAppContext.language = language;
|
||||||
});
|
appContext.setContext(tabletAppContext);
|
||||||
},
|
minimizedAnimation(size);
|
||||||
child: Padding(
|
});
|
||||||
padding: const EdgeInsets.all(8.0),
|
},
|
||||||
child: Container(
|
child: Padding(
|
||||||
width: 75,
|
padding: const EdgeInsets.all(8.0),
|
||||||
height: 75,
|
child: Container(
|
||||||
decoration: flagDecoration(language),
|
width: 35,
|
||||||
|
height: 35,
|
||||||
|
decoration: flagDecoration(language),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
)
|
||||||
)
|
]
|
||||||
]
|
],
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/rendering.dart';
|
import 'package:flutter/rendering.dart';
|
||||||
@ -7,13 +9,18 @@ import 'package:manager_api/api.dart';
|
|||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:tablet_app/Components/loading.dart';
|
import 'package:tablet_app/Components/loading.dart';
|
||||||
import 'package:tablet_app/Components/loading_common.dart';
|
import 'package:tablet_app/Components/loading_common.dart';
|
||||||
|
import 'package:tablet_app/Helpers/DatabaseHelper.dart';
|
||||||
import 'package:tablet_app/Helpers/MQTTHelper.dart';
|
import 'package:tablet_app/Helpers/MQTTHelper.dart';
|
||||||
|
import 'package:tablet_app/Screens/Agenda/agenda_view.dart';
|
||||||
|
import 'package:tablet_app/Screens/Article/article_view.dart';
|
||||||
import 'package:tablet_app/Screens/Configuration/config_view.dart';
|
import 'package:tablet_app/Screens/Configuration/config_view.dart';
|
||||||
import 'package:tablet_app/Screens/Map/map_context.dart';
|
import 'package:tablet_app/Screens/Map/map_context.dart';
|
||||||
import 'package:tablet_app/Screens/Map/map_view.dart';
|
import 'package:tablet_app/Screens/Map/map_view.dart';
|
||||||
import 'package:tablet_app/Models/map-marker.dart';
|
import 'package:tablet_app/Models/map-marker.dart';
|
||||||
import 'package:tablet_app/Models/tabletContext.dart';
|
import 'package:tablet_app/Models/tabletContext.dart';
|
||||||
import 'package:tablet_app/Screens/Menu/menu_view.dart';
|
import 'package:tablet_app/Screens/Menu/menu_view.dart';
|
||||||
|
import 'package:tablet_app/Screens/PDF/pdf_view.dart';
|
||||||
|
import 'package:tablet_app/Screens/Puzzle/puzzle_view.dart';
|
||||||
import 'package:tablet_app/Screens/Slider/slider_view.dart';
|
import 'package:tablet_app/Screens/Slider/slider_view.dart';
|
||||||
import 'package:tablet_app/Screens/Video/video_view.dart';
|
import 'package:tablet_app/Screens/Video/video_view.dart';
|
||||||
import 'package:tablet_app/Screens/Web/web_view.dart';
|
import 'package:tablet_app/Screens/Web/web_view.dart';
|
||||||
@ -42,11 +49,11 @@ class _MainViewWidget extends State<MainViewWidget> {
|
|||||||
final appContext = Provider.of<AppContext>(context);
|
final appContext = Provider.of<AppContext>(context);
|
||||||
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: []);
|
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: []);
|
||||||
Size size = MediaQuery.of(context).size;
|
Size size = MediaQuery.of(context).size;
|
||||||
|
|
||||||
configurationDTO = appContext.getContext().configuration;
|
configurationDTO = appContext.getContext().configuration;
|
||||||
|
|
||||||
if (!MQTTHelper.instance.isInstantiated)
|
// TODO REMOVE
|
||||||
MQTTHelper.instance.connect(appContext);
|
/*if (!MQTTHelper.instance.isInstantiated)
|
||||||
|
MQTTHelper.instance.connect(appContext);*/
|
||||||
|
|
||||||
if(sectionSelected != null) {
|
if(sectionSelected != null) {
|
||||||
var elementToShow;
|
var elementToShow;
|
||||||
@ -70,17 +77,29 @@ class _MainViewWidget extends State<MainViewWidget> {
|
|||||||
elementToShow = WebView(section: sectionSelected);
|
elementToShow = WebView(section: sectionSelected);
|
||||||
break;
|
break;
|
||||||
case SectionType.video : // Video
|
case SectionType.video : // Video
|
||||||
elementToShow = VideoViewWidget(section: sectionSelected);
|
elementToShow = VideoView(section: sectionSelected);
|
||||||
break;
|
break;
|
||||||
case SectionType.slider :
|
case SectionType.slider :
|
||||||
elementToShow = SliderViewWidget(section: sectionSelected);
|
elementToShow = SliderView(section: sectionSelected);
|
||||||
break;
|
break;
|
||||||
case SectionType.menu :
|
case SectionType.menu :
|
||||||
elementToShow = MenuViewWidget(section: sectionSelected!);
|
elementToShow = MenuView(section: sectionSelected!);
|
||||||
break;
|
break;
|
||||||
case SectionType.quizz :
|
case SectionType.quizz :
|
||||||
elementToShow = QuizzViewWidget(section: sectionSelected);
|
elementToShow = QuizzView(section: sectionSelected);
|
||||||
break;
|
break;
|
||||||
|
case SectionType.pdf :
|
||||||
|
elementToShow = PDFViewWidget(section: sectionSelected);
|
||||||
|
break;
|
||||||
|
case SectionType.puzzle :
|
||||||
|
elementToShow = PuzzleView(section: sectionSelected);
|
||||||
|
break;
|
||||||
|
case SectionType.agenda :
|
||||||
|
elementToShow = AgendaView(section: sectionSelected);
|
||||||
|
break;
|
||||||
|
/*case SectionType.article : // TODO
|
||||||
|
elementToShow = ArticleView(section: sectionSelected);
|
||||||
|
break;*/
|
||||||
default:
|
default:
|
||||||
elementToShow = Text("Ce type n'est pas supporté");
|
elementToShow = Text("Ce type n'est pas supporté");
|
||||||
break;
|
break;
|
||||||
@ -132,7 +151,7 @@ class _MainViewWidget extends State<MainViewWidget> {
|
|||||||
alignment: Alignment.centerLeft,
|
alignment: Alignment.centerLeft,
|
||||||
child: HtmlWidget(
|
child: HtmlWidget(
|
||||||
sectionSelected!.title!.firstWhere((translation) => translation.language == appContext.getContext().language).value!,
|
sectionSelected!.title!.firstWhere((translation) => translation.language == appContext.getContext().language).value!,
|
||||||
textStyle: new TextStyle(fontSize: kIsWeb ? kWebSectionTitleDetailSize : kSectionTitleDetailSize),
|
textStyle: new TextStyle(fontSize: kIsWeb ? kWebSectionTitleDetailSize : kSectionTitleDetailSize, color: Colors.white),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
@ -181,10 +200,10 @@ class _MainViewWidget extends State<MainViewWidget> {
|
|||||||
),
|
),
|
||||||
floatingActionButtonLocation: FloatingActionButtonLocation.endTop,
|
floatingActionButtonLocation: FloatingActionButtonLocation.endTop,
|
||||||
floatingActionButton: Padding(
|
floatingActionButton: Padding(
|
||||||
padding: const EdgeInsets.only(top: kIsWeb ? 16.0 : 0.0),
|
padding: const EdgeInsets.only(top: kIsWeb ? 16.0 : 16.0),
|
||||||
child: Container(
|
child: Container(
|
||||||
height: kIsWeb ? size.height *0.08 : 185.0,
|
height: kIsWeb ? size.height *0.08 : size.height *0.08,
|
||||||
width: kIsWeb ? size.width *0.08: 185.0,
|
width: kIsWeb ? size.width *0.08: size.width *0.08,
|
||||||
child: FittedBox(
|
child: FittedBox(
|
||||||
child: FloatingActionButton.extended(
|
child: FloatingActionButton.extended(
|
||||||
backgroundColor: kBackgroundColor,
|
backgroundColor: kBackgroundColor,
|
||||||
@ -196,7 +215,7 @@ class _MainViewWidget extends State<MainViewWidget> {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
icon: Icon(Icons.arrow_back, color: Colors.grey),
|
icon: Icon(Icons.arrow_back, color: Colors.grey),
|
||||||
label: Text("Menu")
|
label: Text("Menu", style: TextStyle(color: Colors.black))
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -218,28 +237,28 @@ class _MainViewWidget extends State<MainViewWidget> {
|
|||||||
),
|
),
|
||||||
) : null,
|
) : null,
|
||||||
child: Stack(
|
child: Stack(
|
||||||
children: [
|
children: [
|
||||||
LanguageSelection(size: size),
|
LanguageSelection(size: size),
|
||||||
Center(
|
Center(
|
||||||
child: Container(
|
child: Container(
|
||||||
height: kIsWeb ? size.height : size.height * 0.85,
|
height: kIsWeb ? size.height : size.height * 0.85,
|
||||||
width: size.width * 0.9,
|
width: size.width * 0.9,
|
||||||
child: FutureBuilder(
|
child: FutureBuilder(
|
||||||
future: getSections(appContext),
|
future: getSections(appContext),
|
||||||
builder: (context, AsyncSnapshot<dynamic> snapshot) {
|
builder: (context, AsyncSnapshot<dynamic> snapshot) {
|
||||||
if (snapshot.connectionState == ConnectionState.done) {
|
if (snapshot.connectionState == ConnectionState.done) {
|
||||||
if (snapshot.data == null) {
|
if (snapshot.data == null) {
|
||||||
// Show select config
|
// Show select config
|
||||||
return Text("");
|
return Text("");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return Center(
|
return Center(
|
||||||
child: GridView.builder(
|
child: GridView.builder(
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: rowCount),
|
gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: rowCount),
|
||||||
itemCount: snapshot.data?.length,
|
itemCount: snapshot.data?.length,
|
||||||
itemBuilder: (BuildContext context, int index) {
|
itemBuilder: (BuildContext context, int index) {
|
||||||
return InkWell(
|
return InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
sectionSelected = snapshot.data[index];
|
sectionSelected = snapshot.data[index];
|
||||||
@ -252,60 +271,134 @@ class _MainViewWidget extends State<MainViewWidget> {
|
|||||||
child: Align(
|
child: Align(
|
||||||
alignment: Alignment.bottomRight,
|
alignment: Alignment.bottomRight,
|
||||||
child: FractionallySizedBox(
|
child: FractionallySizedBox(
|
||||||
heightFactor: 0.25,
|
heightFactor: 0.35,
|
||||||
child: Column(
|
child: Container(
|
||||||
children: [
|
color: Colors.green,
|
||||||
Align(
|
child: Column(
|
||||||
alignment: Alignment.centerRight,
|
children: [
|
||||||
child: HtmlWidget(
|
Container(
|
||||||
snapshot.data[index].title.firstWhere((translation) => translation.language == appContext.getContext().language).value,
|
color: Colors.blue,
|
||||||
customStylesBuilder: (element) {
|
child: LayoutBuilder(
|
||||||
return {'text-align': 'right'};
|
builder: (BuildContext context, BoxConstraints constraints) {
|
||||||
},
|
return SizedBox(
|
||||||
textStyle: new TextStyle(fontSize: kIsWeb ? kWebMenuTitleDetailSize: kMenuTitleDetailSize),
|
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)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
Container(color: Colors.orange, child: Text("ds")),
|
||||||
Align(
|
|
||||||
alignment: Alignment.centerRight,
|
/*Container(
|
||||||
child: HtmlWidget(
|
color: Colors.orange,
|
||||||
snapshot.data[index].description.firstWhere((translation) => translation.language == appContext.getContext().language).value,
|
child: FittedBox(
|
||||||
customStylesBuilder: (element) {
|
fit: BoxFit.fitWidth,
|
||||||
return {'text-align': 'right'};
|
child: Align(
|
||||||
},
|
alignment: Alignment.centerRight,
|
||||||
textStyle: new TextStyle(fontSize: kIsWeb ? kWebMenuDescriptionDetailSize: kMenuDescriptionDetailSize, fontFamily: ""),
|
child: HtmlWidget(
|
||||||
),
|
snapshot.data[index].title.firstWhere((translation) => translation.language == appContext.getContext().language).value,
|
||||||
),
|
customStylesBuilder: (element) {
|
||||||
],
|
return {'text-align': 'right'};
|
||||||
|
},
|
||||||
|
textStyle: new TextStyle(fontSize: calculateFontSize(context, kIsWeb ? kWebMenuTitleDetailSize: kMenuTitleDetailSize)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
FittedBox(
|
||||||
|
fit: BoxFit.fill,
|
||||||
|
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: new TextStyle(fontSize: calculateFontSize(context, kIsWeb ? kWebMenuDescriptionDetailSize: kMenuDescriptionDetailSize), fontFamily: ""),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),*/
|
||||||
|
],
|
||||||
|
),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else if (snapshot.connectionState == ConnectionState.none) {
|
||||||
|
return Text("No data");
|
||||||
|
} else {
|
||||||
|
return Center(
|
||||||
|
child: Container(
|
||||||
|
child: LoadingCommon()
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else if (snapshot.connectionState == ConnectionState.none) {
|
|
||||||
return Text("No data");
|
|
||||||
} else {
|
|
||||||
return Center(
|
|
||||||
child: Container(
|
|
||||||
child: LoadingCommon()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
]),
|
||||||
]),
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<ConfigurationDTO?> getCurrentConfiguration(dynamic appContext) async {
|
||||||
|
TabletAppContext tabletAppContext = await appContext.getContext();
|
||||||
|
try {
|
||||||
|
ConfigurationDTO? configurationDTO = await tabletAppContext.clientAPI!.configurationApi!.configurationGetDetail(tabletAppContext.configuration!.id!);
|
||||||
|
|
||||||
|
tabletAppContext.configuration = configurationDTO;
|
||||||
|
|
||||||
|
TabletAppContext? localContext = await DatabaseHelper.instance.getData();
|
||||||
|
if (localContext != null) { // Check if sql DB exist
|
||||||
|
await DatabaseHelper.instance.update(tabletAppContext);
|
||||||
|
} else {
|
||||||
|
await DatabaseHelper.instance.insert(tabletAppContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
appContext.setContext(tabletAppContext);
|
||||||
|
// STORE IT LOCALLY (SQLite)
|
||||||
|
TabletAppContext? localContext = await DatabaseHelper.instance.getData();
|
||||||
|
if (localContext != null) { // Check if sql DB exist
|
||||||
|
await DatabaseHelper.instance.update(tabletAppContext);
|
||||||
|
} else {
|
||||||
|
await DatabaseHelper.instance.insert(tabletAppContext);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
return configurationDTO;
|
||||||
|
} catch (e) {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
const SnackBar(
|
||||||
|
content: Text('Une erreur est survenue lors de la récupération de la configuration'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Future<List<SectionDTO>?> getSections(dynamic appContext) async {
|
Future<List<SectionDTO>?> getSections(dynamic appContext) async {
|
||||||
TabletAppContext tabletAppContext = await appContext.getContext();
|
TabletAppContext tabletAppContext = await appContext.getContext();
|
||||||
|
|
||||||
|
await getCurrentConfiguration(appContext);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
List<SectionDTO>? sections = await tabletAppContext.clientAPI!.sectionApi!.sectionGetFromConfiguration(tabletAppContext.configuration!.id!);
|
List<SectionDTO>? sections = await tabletAppContext.clientAPI!.sectionApi!.sectionGetFromConfiguration(tabletAppContext.configuration!.id!);
|
||||||
sections!.sort((a, b) => a.order!.compareTo(b.order!));
|
sections!.sort((a, b) => a.order!.compareTo(b.order!));
|
||||||
@ -326,6 +419,21 @@ class _MainViewWidget extends State<MainViewWidget> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double calculateFontSize(double parentWidth, double parentHeight, double baseSize) {
|
||||||
|
// La taille de base est basée sur la taille définie dans vos constantes (kWebMenuTitleDetailSize ou kMenuTitleDetailSize).
|
||||||
|
// Vous pouvez ajuster ce facteur en fonction de vos besoins.
|
||||||
|
double scaleFactor = 0.8;
|
||||||
|
|
||||||
|
// Calculez la taille de la police en fonction de la largeur et de la hauteur maximales disponibles
|
||||||
|
//double calculatedFontSize = parentWidth * scaleFactor;
|
||||||
|
|
||||||
|
// Vous pouvez également prendre en compte la hauteur ici si nécessaire
|
||||||
|
double calculatedFontSize = min(parentWidth, parentHeight) * scaleFactor;
|
||||||
|
|
||||||
|
// Utilisez la plus petite valeur entre la taille de base et la taille calculée
|
||||||
|
return calculatedFontSize < baseSize ? calculatedFontSize : baseSize;
|
||||||
|
}
|
||||||
|
|
||||||
boxDecoration(SectionDTO section, bool isSelected) {
|
boxDecoration(SectionDTO section, bool isSelected) {
|
||||||
return BoxDecoration(
|
return BoxDecoration(
|
||||||
color: kBackgroundLight,
|
color: kBackgroundLight,
|
||||||
|
|||||||
@ -42,7 +42,7 @@ class _GoogleMapViewState extends State<GoogleMapView> {
|
|||||||
description: point.description!.firstWhere((translation) => translation.language == language).value,
|
description: point.description!.firstWhere((translation) => translation.language == language).value,
|
||||||
longitude: point.longitude,
|
longitude: point.longitude,
|
||||||
latitude: point.latitude,
|
latitude: point.latitude,
|
||||||
images: point.images
|
contents: point.contents
|
||||||
);
|
);
|
||||||
markersList.add(mapMarker);
|
markersList.add(mapMarker);
|
||||||
});
|
});
|
||||||
@ -65,7 +65,7 @@ class _GoogleMapViewState extends State<GoogleMapView> {
|
|||||||
mapContext.setSelectedMarker(
|
mapContext.setSelectedMarker(
|
||||||
new MapMarker(
|
new MapMarker(
|
||||||
title: element.title,
|
title: element.title,
|
||||||
images: element.images,
|
contents: element.contents,
|
||||||
description: element.description,
|
description: element.description,
|
||||||
longitude: element.longitude,
|
longitude: element.longitude,
|
||||||
latitude: element.latitude,
|
latitude: element.latitude,
|
||||||
@ -145,7 +145,7 @@ class _GoogleMapViewState extends State<GoogleMapView> {
|
|||||||
new MapMarker(
|
new MapMarker(
|
||||||
title: '',
|
title: '',
|
||||||
description: '',
|
description: '',
|
||||||
images: null,
|
contents: null,
|
||||||
longitude: null,
|
longitude: null,
|
||||||
latitude: null
|
latitude: null
|
||||||
));
|
));
|
||||||
|
|||||||
@ -65,12 +65,12 @@ class _MarkerInfoWidget extends State<MarkerViewWidget> {
|
|||||||
child: Stack(
|
child: Stack(
|
||||||
children: <Widget> [
|
children: <Widget> [
|
||||||
Positioned(
|
Positioned(
|
||||||
right: 15,
|
right: 5,
|
||||||
top: 15,
|
top: 5,
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
mapContext.setSelectedMarker(new MapMarker(longitude: null, latitude: null, title: '', images: null, description: ''));
|
mapContext.setSelectedMarker(new MapMarker(longitude: null, latitude: null, title: '', contents: null, description: ''));
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
@ -90,7 +90,7 @@ class _MarkerInfoWidget extends State<MarkerViewWidget> {
|
|||||||
),
|
),
|
||||||
child: Icon(
|
child: Icon(
|
||||||
Icons.close,
|
Icons.close,
|
||||||
size: 35,
|
size: 25,
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -223,8 +223,8 @@ class _MarkerInfoWidget extends State<MarkerViewWidget> {
|
|||||||
},
|
},
|
||||||
child: Icon(
|
child: Icon(
|
||||||
Icons.chevron_right,
|
Icons.chevron_right,
|
||||||
size: kIsWeb ? 100 : 150,
|
size: kIsWeb ? 100 : 85,
|
||||||
color: kMainRed,
|
color: kTestSecondColor,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
@ -239,8 +239,8 @@ class _MarkerInfoWidget extends State<MarkerViewWidget> {
|
|||||||
},
|
},
|
||||||
child: Icon(
|
child: Icon(
|
||||||
Icons.chevron_left,
|
Icons.chevron_left,
|
||||||
size: kIsWeb ? 100 : 150,
|
size: kIsWeb ? 100 : 85,
|
||||||
color: kMainRed,
|
color: kTestSecondColor,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
|||||||
@ -7,8 +7,11 @@ import 'package:manager_api/api.dart';
|
|||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:tablet_app/Models/map-marker.dart';
|
import 'package:tablet_app/Models/map-marker.dart';
|
||||||
import 'package:tablet_app/Models/tabletContext.dart';
|
import 'package:tablet_app/Models/tabletContext.dart';
|
||||||
|
import 'package:tablet_app/Screens/Agenda/agenda_view.dart';
|
||||||
import 'package:tablet_app/Screens/Map/map_context.dart';
|
import 'package:tablet_app/Screens/Map/map_context.dart';
|
||||||
import 'package:tablet_app/Screens/Map/map_view.dart';
|
import 'package:tablet_app/Screens/Map/map_view.dart';
|
||||||
|
import 'package:tablet_app/Screens/PDF/pdf_view.dart';
|
||||||
|
import 'package:tablet_app/Screens/Puzzle/puzzle_view.dart';
|
||||||
import 'package:tablet_app/Screens/Quizz/quizz_view.dart';
|
import 'package:tablet_app/Screens/Quizz/quizz_view.dart';
|
||||||
import 'package:tablet_app/Screens/Slider/slider_view.dart';
|
import 'package:tablet_app/Screens/Slider/slider_view.dart';
|
||||||
import 'package:tablet_app/Screens/Video/video_view.dart';
|
import 'package:tablet_app/Screens/Video/video_view.dart';
|
||||||
@ -16,15 +19,15 @@ import 'package:tablet_app/Screens/Web/web_view.dart';
|
|||||||
import 'package:tablet_app/app_context.dart';
|
import 'package:tablet_app/app_context.dart';
|
||||||
import 'package:tablet_app/constants.dart';
|
import 'package:tablet_app/constants.dart';
|
||||||
|
|
||||||
class MenuViewWidget extends StatefulWidget {
|
class MenuView extends StatefulWidget {
|
||||||
final SectionDTO? section;
|
final SectionDTO? section;
|
||||||
MenuViewWidget({this.section});
|
MenuView({this.section});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_MenuViewWidget createState() => _MenuViewWidget();
|
_MenuView createState() => _MenuView();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _MenuViewWidget extends State<MenuViewWidget> {
|
class _MenuView extends State<MenuView> {
|
||||||
MenuDTO menuDTO = MenuDTO();
|
MenuDTO menuDTO = MenuDTO();
|
||||||
SectionDTO? selectedSection;
|
SectionDTO? selectedSection;
|
||||||
@override
|
@override
|
||||||
@ -68,14 +71,26 @@ class _MenuViewWidget extends State<MenuViewWidget> {
|
|||||||
elementToShow = WebView(section: selectedSection);
|
elementToShow = WebView(section: selectedSection);
|
||||||
break;
|
break;
|
||||||
case SectionType.video : // Video
|
case SectionType.video : // Video
|
||||||
elementToShow = VideoViewWidget(section: selectedSection);
|
elementToShow = VideoView(section: selectedSection);
|
||||||
break;
|
break;
|
||||||
case SectionType.slider : // Slider:
|
case SectionType.slider : // Slider
|
||||||
elementToShow = SliderViewWidget(section: selectedSection);
|
elementToShow = SliderView(section: selectedSection);
|
||||||
break;
|
break;
|
||||||
case SectionType.quizz : // Slider:
|
case SectionType.quizz : // Quizz
|
||||||
elementToShow = QuizzViewWidget(section: selectedSection);
|
elementToShow = QuizzView(section: selectedSection);
|
||||||
break;
|
break;
|
||||||
|
case SectionType.pdf : // Pdf
|
||||||
|
elementToShow = PDFViewWidget(section: selectedSection);
|
||||||
|
break;
|
||||||
|
case SectionType.puzzle : // Puzzle
|
||||||
|
elementToShow = PuzzleView(section: selectedSection);
|
||||||
|
break;
|
||||||
|
case SectionType.agenda : // Agenda
|
||||||
|
elementToShow = AgendaView(section: selectedSection);
|
||||||
|
break;
|
||||||
|
/*case SectionType.article : // Article
|
||||||
|
elementToShow = ArticleView(section: selectedSection);
|
||||||
|
break;*/
|
||||||
default:
|
default:
|
||||||
elementToShow = Text('Section type not supported');
|
elementToShow = Text('Section type not supported');
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -28,12 +28,12 @@ class _PDFViewWidget extends State<PDFViewWidget> {
|
|||||||
int? currentPage = 0;
|
int? currentPage = 0;
|
||||||
bool isReady = false;
|
bool isReady = false;
|
||||||
String errorMessage = '';
|
String errorMessage = '';
|
||||||
|
ValueNotifier<Map<String, int>> currentState = ValueNotifier<Map<String, int>>({'page': 0, 'total': 0});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
print(widget.section!.data);
|
print(widget.section!.data);
|
||||||
pdfDTO = PdfDTO.fromJson(jsonDecode(widget.section!.data!))!;
|
pdfDTO = PdfDTO.fromJson(jsonDecode(widget.section!.data!))!;
|
||||||
pdfDTO.source_ = "todo";
|
|
||||||
print(pdfDTO);
|
print(pdfDTO);
|
||||||
super.initState();
|
super.initState();
|
||||||
|
|
||||||
@ -52,8 +52,7 @@ class _PDFViewWidget extends State<PDFViewWidget> {
|
|||||||
try {
|
try {
|
||||||
// "https://berlin2017.droidcon.cod.newthinking.net/sites/global.droidcon.cod.newthinking.net/files/media/documents/Flutter%20-%2060FPS%20UI%20of%20the%20future%20%20-%20DroidconDE%2017.pdf";
|
// "https://berlin2017.droidcon.cod.newthinking.net/sites/global.droidcon.cod.newthinking.net/files/media/documents/Flutter%20-%2060FPS%20UI%20of%20the%20future%20%20-%20DroidconDE%2017.pdf";
|
||||||
// final url = "https://pdfkit.org/docs/guide.pdf";
|
// final url = "https://pdfkit.org/docs/guide.pdf";
|
||||||
final url = "http://www.pdf995.com/samples/pdf.pdf";
|
final url = source_;
|
||||||
// TODO replace by source_
|
|
||||||
final filename = url.substring(url.lastIndexOf("/") + 1);
|
final filename = url.substring(url.lastIndexOf("/") + 1);
|
||||||
var request = await HttpClient().getUrl(Uri.parse(url));
|
var request = await HttpClient().getUrl(Uri.parse(url));
|
||||||
var response = await request.close();
|
var response = await request.close();
|
||||||
@ -80,37 +79,60 @@ class _PDFViewWidget extends State<PDFViewWidget> {
|
|||||||
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) => pdfDTO.source_ != null && pdfDTO.source_!.length > 0 ?
|
Widget build(BuildContext context) => pdfDTO.resourceUrl != null && pdfDTO.resourceUrl!.length > 0 ?
|
||||||
FutureBuilder(
|
FutureBuilder(
|
||||||
future: createFileOfPdfUrl(""),
|
future: createFileOfPdfUrl(pdfDTO.resourceUrl!),
|
||||||
builder: (context, AsyncSnapshot<dynamic> snapshot) {
|
builder: (context, AsyncSnapshot<dynamic> snapshot) {
|
||||||
print("snapshot.data");
|
print("snapshot.data");
|
||||||
print(snapshot.data);
|
print(snapshot.data);
|
||||||
if (snapshot.connectionState == ConnectionState.done) {
|
if (snapshot.connectionState == ConnectionState.done) {
|
||||||
return PDFView(
|
return Stack(
|
||||||
filePath: snapshot.data.path,
|
children: [
|
||||||
enableSwipe: true,
|
PDFView(
|
||||||
swipeHorizontal: true,
|
filePath: snapshot.data.path,
|
||||||
autoSpacing: true,
|
enableSwipe: true,
|
||||||
pageFling: true,
|
swipeHorizontal: true,
|
||||||
onRender: (_pages) {
|
autoSpacing: true,
|
||||||
//setState(() {
|
pageFling: true,
|
||||||
pages = _pages;
|
fitPolicy: FitPolicy.HEIGHT,
|
||||||
isReady = true;
|
onRender: (_pages) {
|
||||||
//});
|
//setState(() {
|
||||||
},
|
pages = _pages;
|
||||||
onError: (error) {
|
isReady = true;
|
||||||
print(error.toString());
|
//});
|
||||||
},
|
},
|
||||||
onPageError: (page, error) {
|
onError: (error) {
|
||||||
print('$page: ${error.toString()}');
|
print(error.toString());
|
||||||
},
|
},
|
||||||
onViewCreated: (PDFViewController pdfViewController) {
|
onPageError: (page, error) {
|
||||||
//_controller.complete(pdfViewController);
|
print('$page: ${error.toString()}');
|
||||||
},
|
},
|
||||||
onPageChanged: (int? page, int? total) {
|
onViewCreated: (PDFViewController pdfViewController) {
|
||||||
print('page change: $page/$total');
|
//_controller.complete(pdfViewController);
|
||||||
},
|
},
|
||||||
|
onPageChanged: (int? page, int? total) {
|
||||||
|
currentPage = page;
|
||||||
|
pages = total;
|
||||||
|
currentState.value = {'page': page!, 'total': total!};
|
||||||
|
|
||||||
|
print('page change: $page/$total');
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
bottom: 20,
|
||||||
|
right: 20,
|
||||||
|
child: ValueListenableBuilder<Map<String, int>>(
|
||||||
|
valueListenable: currentState,
|
||||||
|
builder: (context, value, _) {
|
||||||
|
return Container(
|
||||||
|
//color: Colors.blueAccent,
|
||||||
|
child: Text("${value["page"]!+1}/${value["total"]!}",
|
||||||
|
style: TextStyle(color: Colors.black, fontSize: 30))
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return Center(
|
return Center(
|
||||||
|
|||||||
@ -35,7 +35,7 @@ class CorrectOverlayState extends State<CorrectOverlay>
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return new Material(
|
return new Container(
|
||||||
color: Colors.black54,
|
color: Colors.black54,
|
||||||
child: new InkWell(
|
child: new InkWell(
|
||||||
onTap: () => widget._onTap(),
|
onTap: () => widget._onTap(),
|
||||||
@ -44,7 +44,7 @@ class CorrectOverlayState extends State<CorrectOverlay>
|
|||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
new Container(
|
new Container(
|
||||||
decoration: new BoxDecoration(
|
decoration: new BoxDecoration(
|
||||||
color: Colors.white, shape: BoxShape.circle),
|
color: Colors.blueAccent, shape: BoxShape.circle),
|
||||||
child: new Transform.rotate(
|
child: new Transform.rotate(
|
||||||
angle: _iconAnimation.value * 2 * math.pi,
|
angle: _iconAnimation.value * 2 * math.pi,
|
||||||
child: new Icon(
|
child: new Icon(
|
||||||
|
|||||||
89
lib/Screens/Puzzle/message_dialog.dart
Normal file
89
lib/Screens/Puzzle/message_dialog.dart
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_widget_from_html/flutter_widget_from_html.dart';
|
||||||
|
import 'package:manager_api/api.dart';
|
||||||
|
import 'package:tablet_app/Components/show_element_for_resource.dart';
|
||||||
|
import 'package:tablet_app/app_context.dart';
|
||||||
|
import 'package:tablet_app/constants.dart';
|
||||||
|
|
||||||
|
void showMessage(TranslationAndResourceDTO translationAndResourceDTO, AppContext appContext, BuildContext context, Size size) {
|
||||||
|
print("translationAndResourceDTO");
|
||||||
|
print(translationAndResourceDTO);
|
||||||
|
showDialog(
|
||||||
|
builder: (BuildContext context) => AlertDialog(
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(20.0))
|
||||||
|
),
|
||||||
|
content: SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
if(translationAndResourceDTO.resourceId != null)
|
||||||
|
Container(
|
||||||
|
//color: Colors.cyan,
|
||||||
|
height: size.height *0.45,
|
||||||
|
width: size.width *0.5,
|
||||||
|
child: Center(
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
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),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
//color: Colors.green,
|
||||||
|
height: size.height *0.3,
|
||||||
|
width: size.width *0.5,
|
||||||
|
child: Center(
|
||||||
|
child: Align(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: HtmlWidget(
|
||||||
|
translationAndResourceDTO.value!,
|
||||||
|
customStylesBuilder: (element) {
|
||||||
|
return {'text-align': 'center'};
|
||||||
|
},
|
||||||
|
textStyle: TextStyle(fontSize: kDescriptionSize),
|
||||||
|
),/*Text(
|
||||||
|
resourceDTO.label == null ? "" : resourceDTO.label,
|
||||||
|
style: new TextStyle(fontSize: 25, fontWeight: FontWeight.w400)),*/
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
/*actions: <Widget>[
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: Align(
|
||||||
|
alignment: AlignmentDirectional.bottomEnd,
|
||||||
|
child: Container(
|
||||||
|
width: 175,
|
||||||
|
height: 70,
|
||||||
|
child: RoundedButton(
|
||||||
|
text: "Merci",
|
||||||
|
icon: Icons.undo,
|
||||||
|
color: kSecondGrey,
|
||||||
|
press: () {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
fontSize: 20,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],*/
|
||||||
|
), context: context
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -1,6 +1,10 @@
|
|||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:tablet_app/Models/tabletContext.dart';
|
||||||
|
import 'package:tablet_app/app_context.dart';
|
||||||
|
import 'package:tablet_app/constants.dart';
|
||||||
|
|
||||||
class PuzzlePiece extends StatefulWidget {
|
class PuzzlePiece extends StatefulWidget {
|
||||||
final Image image;
|
final Image image;
|
||||||
@ -49,14 +53,38 @@ class _PuzzlePieceState extends State<PuzzlePiece> {
|
|||||||
// can we move the piece ?
|
// can we move the piece ?
|
||||||
bool isMovable = true;
|
bool isMovable = true;
|
||||||
|
|
||||||
|
GlobalKey _widgetPieceKey = GlobalKey();
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
setState(() {
|
||||||
|
|
||||||
|
RenderBox renderBox = _widgetPieceKey.currentContext?.findRenderObject() as RenderBox;
|
||||||
|
Size size = renderBox.size;
|
||||||
|
|
||||||
|
final appContext = Provider.of<AppContext>(context, listen: false);
|
||||||
|
TabletAppContext tabletAppContext = appContext.getContext();
|
||||||
|
tabletAppContext.puzzleSize = size;
|
||||||
|
appContext.setContext(tabletAppContext);
|
||||||
|
|
||||||
|
if(widget.row == 0 && widget.col == 0) {
|
||||||
|
widget.sendToBack(widget);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
// the image width
|
|
||||||
final imageWidth = MediaQuery.of(context).size.width;
|
var isPortrait = MediaQuery.of(context).orientation == Orientation.portrait;
|
||||||
// the image height
|
|
||||||
final imageHeight = MediaQuery.of(context).size.height *
|
var imageHeight = isPortrait ? widget.imageSize.width/1.5 : widget.imageSize.width;
|
||||||
MediaQuery.of(context).size.width /
|
var imageWidth = isPortrait ? widget.imageSize.width/1.5: widget.imageSize.height;
|
||||||
widget.imageSize.width;
|
|
||||||
final pieceWidth = imageWidth / widget.maxCol;
|
final pieceWidth = imageWidth / widget.maxCol;
|
||||||
final pieceHeight = imageHeight / widget.maxRow;
|
final pieceHeight = imageHeight / widget.maxRow;
|
||||||
|
|
||||||
@ -64,60 +92,74 @@ class _PuzzlePieceState extends State<PuzzlePiece> {
|
|||||||
top = Random().nextInt((imageHeight - pieceHeight).ceil()).toDouble();
|
top = Random().nextInt((imageHeight - pieceHeight).ceil()).toDouble();
|
||||||
var test = top!;
|
var test = top!;
|
||||||
test -= widget.row * pieceHeight;
|
test -= widget.row * pieceHeight;
|
||||||
top = test;
|
top = test /2.2; // TODO change ?
|
||||||
}
|
}
|
||||||
|
|
||||||
if (left == null) {
|
if (left == null) {
|
||||||
left = Random().nextInt((imageWidth - pieceWidth).ceil()).toDouble();
|
left = Random().nextInt((imageWidth - pieceWidth).ceil()).toDouble();
|
||||||
var test = left!;
|
var test = left!;
|
||||||
test -= widget.col * pieceWidth;
|
test -= widget.col * pieceWidth;
|
||||||
left = test;
|
left = test /2.2; // TODO change ?
|
||||||
|
}
|
||||||
|
|
||||||
|
if(widget.row == 0 && widget.col == 0) {
|
||||||
|
top = 0;
|
||||||
|
left = 0;
|
||||||
|
isMovable = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Positioned(
|
return Positioned(
|
||||||
top: top,
|
top: top,
|
||||||
left: left,
|
left: left,
|
||||||
width: imageWidth,
|
width: imageWidth,
|
||||||
child: GestureDetector(
|
child: Container(
|
||||||
onTap: () {
|
key: _widgetPieceKey,
|
||||||
if (isMovable) {
|
decoration: widget.col == 0 && widget.row == 0 ? BoxDecoration(
|
||||||
widget.bringToTop(widget);
|
border: Border.all(
|
||||||
}
|
color: Colors.black,
|
||||||
},
|
width: 0.5,
|
||||||
onPanStart: (_) {
|
),
|
||||||
if (isMovable) {
|
) : null,
|
||||||
widget.bringToTop(widget);
|
child: GestureDetector(
|
||||||
}
|
onTap: () {
|
||||||
},
|
if (isMovable) {
|
||||||
onPanUpdate: (dragUpdateDetails) {
|
widget.bringToTop(widget);
|
||||||
if (isMovable) {
|
}
|
||||||
setState(() {
|
},
|
||||||
var testTop = top!;
|
onPanStart: (_) {
|
||||||
var testLeft = left!;
|
if (isMovable) {
|
||||||
testTop = top!;
|
widget.bringToTop(widget);
|
||||||
testLeft = left!;
|
}
|
||||||
testTop += dragUpdateDetails.delta.dy;
|
},
|
||||||
testLeft += dragUpdateDetails.delta.dx;
|
onPanUpdate: (dragUpdateDetails) {
|
||||||
top = testTop!;
|
if (isMovable) {
|
||||||
left = testLeft!;
|
setState(() {
|
||||||
|
var testTop = top!;
|
||||||
|
var testLeft = left!;
|
||||||
|
testTop = top!;
|
||||||
|
testLeft = left!;
|
||||||
|
testTop += dragUpdateDetails.delta.dy;
|
||||||
|
testLeft += dragUpdateDetails.delta.dx;
|
||||||
|
top = testTop;
|
||||||
|
left = testLeft;
|
||||||
|
|
||||||
if (-10 < top! && top! < 10 && -10 < left! && left! < 10) {
|
if (-10 < top! && top! < 10 && -10 < left! && left! < 10) {
|
||||||
top = 0;
|
top = 0;
|
||||||
left = 0;
|
left = 0;
|
||||||
isMovable = false;
|
isMovable = false;
|
||||||
widget.sendToBack(widget);
|
widget.sendToBack(widget);
|
||||||
|
}
|
||||||
//ScoreWidget.of(context).allInPlaceCount++;
|
});
|
||||||
}
|
}
|
||||||
});
|
},
|
||||||
}
|
child: ClipPath(
|
||||||
},
|
child: CustomPaint(
|
||||||
child: ClipPath(
|
foregroundPainter: PuzzlePiecePainter(
|
||||||
child: CustomPaint(
|
widget.row, widget.col, widget.maxRow, widget.maxCol),
|
||||||
foregroundPainter: PuzzlePiecePainter(
|
child: widget.image),
|
||||||
widget.row, widget.col, widget.maxRow, widget.maxCol),
|
clipper: PuzzlePieceClipper(
|
||||||
child: widget.image),
|
widget.row, widget.col, widget.maxRow, widget.maxCol),
|
||||||
clipper: PuzzlePieceClipper(
|
),
|
||||||
widget.row, widget.col, widget.maxRow, widget.maxCol),
|
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -153,9 +195,9 @@ class PuzzlePiecePainter extends CustomPainter {
|
|||||||
@override
|
@override
|
||||||
void paint(Canvas canvas, Size size) {
|
void paint(Canvas canvas, Size size) {
|
||||||
final Paint paint = Paint()
|
final Paint paint = Paint()
|
||||||
..color = Color(0x80FFFFFF)
|
..color = Colors.black//Color(0x80FFFFFF)
|
||||||
..style = PaintingStyle.stroke
|
..style = PaintingStyle.stroke
|
||||||
..strokeWidth = 1.0;
|
..strokeWidth = 2.5;
|
||||||
|
|
||||||
canvas.drawPath(getPiecePath(size, row, col, maxRow, maxCol), paint);
|
canvas.drawPath(getPiecePath(size, row, col, maxRow, maxCol), paint);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,11 @@ import 'dart:io';
|
|||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:manager_api/api.dart';
|
import 'package:manager_api/api.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:tablet_app/Components/loading_common.dart';
|
||||||
|
import 'package:tablet_app/Models/tabletContext.dart';
|
||||||
|
import 'package:tablet_app/Screens/Puzzle/message_dialog.dart';
|
||||||
|
import 'package:tablet_app/app_context.dart';
|
||||||
import 'puzzle_piece.dart';
|
import 'puzzle_piece.dart';
|
||||||
import 'score_widget.dart';
|
import 'score_widget.dart';
|
||||||
|
|
||||||
@ -14,49 +19,61 @@ class PuzzleView extends StatefulWidget {
|
|||||||
PuzzleView({this.section});
|
PuzzleView({this.section});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_PuzzleViewWidget createState() => _PuzzleViewWidget();
|
_PuzzleView createState() => _PuzzleView();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _PuzzleViewWidget extends State<PuzzleView> {
|
class _PuzzleView extends State<PuzzleView> {
|
||||||
SliderDTO sliderDTO = SliderDTO();
|
PuzzleDTO puzzleDTO = PuzzleDTO();
|
||||||
final int rows = 3;
|
|
||||||
final int cols = 3;
|
int allInPlaceCount = 0;
|
||||||
|
bool isFinished = false;
|
||||||
|
|
||||||
|
GlobalKey _widgetKey = GlobalKey();
|
||||||
|
Size? realWidgetSize;
|
||||||
|
|
||||||
//File? _image;
|
//File? _image;
|
||||||
String? _imagePath;
|
String? _imagePath;
|
||||||
List<Widget> pieces = [];
|
List<Widget> pieces = [];
|
||||||
|
|
||||||
bool _overlayVisible = true;
|
bool isSplittingImage = true;
|
||||||
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
sliderDTO = SliderDTO.fromJson(jsonDecode(widget.section!.data!))!;
|
puzzleDTO = PuzzleDTO.fromJson(jsonDecode(widget.section!.data!))!;
|
||||||
|
|
||||||
|
puzzleDTO.rows = puzzleDTO.rows != null ? puzzleDTO.rows : 3;
|
||||||
|
puzzleDTO.cols = puzzleDTO.cols != null ? puzzleDTO.cols : 3;
|
||||||
|
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
Size size = MediaQuery.of(context).size;
|
||||||
|
final appContext = Provider.of<AppContext>(context, listen: false);
|
||||||
|
TabletAppContext tabletAppContext = appContext.getContext();
|
||||||
|
TranslationAndResourceDTO? messageDebut = puzzleDTO.messageDebut != null ? puzzleDTO.messageDebut!.firstWhere((message) => message.language!.toUpperCase() == tabletAppContext.language!.toUpperCase()) : null;
|
||||||
|
|
||||||
|
if(messageDebut != null) {
|
||||||
|
showMessage(messageDebut, appContext, context, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
getRealWidgetSize();
|
||||||
|
});
|
||||||
|
|
||||||
sliderDTO.images!.sort((a, b) => a.order!.compareTo(b.order!));
|
|
||||||
super.initState();
|
super.initState();
|
||||||
splitImage(Image.network(sliderDTO.images![1].source_!));
|
|
||||||
|
if(puzzleDTO.image != null && puzzleDTO.image!.resourceUrl != null) {
|
||||||
|
splitImage(Image.network(puzzleDTO.image!.resourceUrl!));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*void savePrefs() async {
|
Future<void> getRealWidgetSize() async {
|
||||||
await prefs!.setString(IMAGE_PATH, _imagePath!);
|
RenderBox renderBox = _widgetKey.currentContext?.findRenderObject() as RenderBox;
|
||||||
}*/
|
Size size = renderBox.size;
|
||||||
|
|
||||||
/*Future getImage(ImageSource source) async {
|
setState(() {
|
||||||
var image = await ImagePicker.platform.(source: source);
|
realWidgetSize = size;
|
||||||
|
});
|
||||||
if (image != null) {
|
print("Taille réelle du widget : $size");
|
||||||
setState(() {
|
}
|
||||||
_image = image;
|
|
||||||
_imagePath = _image!.path;
|
|
||||||
pieces.clear();
|
|
||||||
ScoreWidget
|
|
||||||
.of(context)
|
|
||||||
.allInPlaceCount = 0;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
splitImage(Image.file(image));
|
|
||||||
savePrefs();
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// we need to find out the image size, to be used in the PuzzlePiece widget
|
// we need to find out the image size, to be used in the PuzzlePiece widget
|
||||||
Future<Size> getImageSize(Image image) async {
|
Future<Size> getImageSize(Image image) async {
|
||||||
@ -78,9 +95,11 @@ class _PuzzleViewWidget extends State<PuzzleView> {
|
|||||||
// using the rows and columns defined above; each piece will be added to a stack
|
// using the rows and columns defined above; each piece will be added to a stack
|
||||||
void splitImage(Image image) async {
|
void splitImage(Image image) async {
|
||||||
Size imageSize = await getImageSize(image);
|
Size imageSize = await getImageSize(image);
|
||||||
|
//imageSize = realWidgetSize!;
|
||||||
|
imageSize = Size(realWidgetSize!.width * 1.25, realWidgetSize!.height * 1.25);
|
||||||
|
|
||||||
for (int x = 0; x < rows; x++) {
|
for (int x = 0; x < puzzleDTO.rows!; x++) {
|
||||||
for (int y = 0; y < cols; y++) {
|
for (int y = 0; y < puzzleDTO.cols!; y++) {
|
||||||
setState(() {
|
setState(() {
|
||||||
pieces.add(
|
pieces.add(
|
||||||
PuzzlePiece(
|
PuzzlePiece(
|
||||||
@ -89,8 +108,8 @@ class _PuzzleViewWidget extends State<PuzzleView> {
|
|||||||
imageSize: imageSize,
|
imageSize: imageSize,
|
||||||
row: x,
|
row: x,
|
||||||
col: y,
|
col: y,
|
||||||
maxRow: rows,
|
maxRow: puzzleDTO.rows!,
|
||||||
maxCol: cols,
|
maxCol: puzzleDTO.cols!,
|
||||||
bringToTop: this.bringToTop,
|
bringToTop: this.bringToTop,
|
||||||
sendToBack: this.sendToBack,
|
sendToBack: this.sendToBack,
|
||||||
),
|
),
|
||||||
@ -98,6 +117,10 @@ class _PuzzleViewWidget extends State<PuzzleView> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
isSplittingImage = false;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// when the pan of a piece starts, we need to bring it to the front of the stack
|
// when the pan of a piece starts, we need to bring it to the front of the stack
|
||||||
@ -112,38 +135,61 @@ class _PuzzleViewWidget extends State<PuzzleView> {
|
|||||||
// it will be sent to the back of the stack to not get in the way of other, still movable, pieces
|
// it will be sent to the back of the stack to not get in the way of other, still movable, pieces
|
||||||
void sendToBack(Widget widget) {
|
void sendToBack(Widget widget) {
|
||||||
setState(() {
|
setState(() {
|
||||||
|
allInPlaceCount++;
|
||||||
|
isFinished = allInPlaceCount == puzzleDTO.rows! * puzzleDTO.cols!;
|
||||||
pieces.remove(widget);
|
pieces.remove(widget);
|
||||||
pieces.insert(0, widget);
|
pieces.insert(0, widget);
|
||||||
|
|
||||||
|
if(isFinished) {
|
||||||
|
Size size = MediaQuery.of(context).size;
|
||||||
|
final appContext = Provider.of<AppContext>(context, listen: false);
|
||||||
|
TabletAppContext tabletAppContext = appContext.getContext();
|
||||||
|
TranslationAndResourceDTO? messageFin = puzzleDTO.messageFin != null ? puzzleDTO.messageFin!.firstWhere((message) => message.language!.toUpperCase() == tabletAppContext.language!.toUpperCase()) : null;
|
||||||
|
|
||||||
|
if(messageFin != null) {
|
||||||
|
showMessage(messageFin, appContext, context, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
//savePrefs();
|
final appContext = Provider.of<AppContext>(context);
|
||||||
|
TabletAppContext tabletAppContext = appContext.getContext();
|
||||||
|
|
||||||
return SafeArea(
|
return Padding(
|
||||||
child: sliderDTO.images![0].source_! == null
|
key: _widgetKey,
|
||||||
? Center(child: Text('No image selected.'))
|
padding: const EdgeInsets.all(10.0),
|
||||||
: Stack(
|
child: isSplittingImage ? Center(child: LoadingCommon()) :
|
||||||
children: pieces,
|
puzzleDTO.image!.resourceUrl == null || realWidgetSize == null
|
||||||
),
|
? Container(
|
||||||
); /*ScoreWidget
|
width: 50,
|
||||||
.of(context)
|
height: 50,
|
||||||
.allInPlaceCount ==
|
color: Colors.cyan,
|
||||||
rows * cols
|
child: InkWell(onTap: () {
|
||||||
? Overlay(
|
Size size = MediaQuery.of(context).size;
|
||||||
initialEntries: [
|
final appContext = Provider.of<AppContext>(context, listen: false);
|
||||||
OverlayEntry(builder: (context) {
|
TabletAppContext tabletAppContext = appContext.getContext();
|
||||||
return CorrectOverlay(true, () {
|
TranslationAndResourceDTO? messageFin = puzzleDTO.messageFin != null ? puzzleDTO.messageFin!.firstWhere((message) => message.language!.toUpperCase() == tabletAppContext.language!.toUpperCase()) : null;
|
||||||
setState(() {
|
|
||||||
ScoreWidget
|
if(messageFin != null) {
|
||||||
.of(context)
|
// Alert dialog
|
||||||
.allInPlaceCount = 0;
|
showMessage(messageFin, appContext, context, size);
|
||||||
});
|
}
|
||||||
});
|
},),)//Center(child: Text("Invalid image"))
|
||||||
})
|
: Center(
|
||||||
],
|
child: Padding(
|
||||||
)
|
padding: const EdgeInsets.all(8.0),
|
||||||
:*/
|
child: Container(
|
||||||
|
width: tabletAppContext.puzzleSize != null ? tabletAppContext.puzzleSize!.width : realWidgetSize!.width * 0.8,
|
||||||
|
height: tabletAppContext.puzzleSize != null ? tabletAppContext.puzzleSize!.height +1.5 : realWidgetSize!.height * 0.8,
|
||||||
|
child: Stack(
|
||||||
|
children: pieces,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -17,16 +17,16 @@ import 'package:tablet_app/constants.dart';
|
|||||||
import 'drawStrawberry.dart';
|
import 'drawStrawberry.dart';
|
||||||
|
|
||||||
|
|
||||||
class QuizzViewWidget extends StatefulWidget {
|
class QuizzView extends StatefulWidget {
|
||||||
final SectionDTO? section;
|
final SectionDTO? section;
|
||||||
GlobalKey<ScaffoldState>? key;
|
GlobalKey<ScaffoldState>? key;
|
||||||
QuizzViewWidget({this.section, this.key});
|
QuizzView({this.section, this.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_QuizzViewWidget createState() => _QuizzViewWidget();
|
_QuizzView createState() => _QuizzView();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _QuizzViewWidget extends State<QuizzViewWidget> {
|
class _QuizzView extends State<QuizzView> {
|
||||||
ConfettiController? _controllerCenter;
|
ConfettiController? _controllerCenter;
|
||||||
QuizzDTO quizzDTO = QuizzDTO();
|
QuizzDTO quizzDTO = QuizzDTO();
|
||||||
List<QuestionSubDTO> _questionsSubDTO = <QuestionSubDTO>[];
|
List<QuestionSubDTO> _questionsSubDTO = <QuestionSubDTO>[];
|
||||||
@ -303,11 +303,11 @@ class _QuizzViewWidget extends State<QuizzViewWidget> {
|
|||||||
color: kBackgroundLight,
|
color: kBackgroundLight,
|
||||||
shape: BoxShape.rectangle,
|
shape: BoxShape.rectangle,
|
||||||
borderRadius: BorderRadius.circular(20.0),
|
borderRadius: BorderRadius.circular(20.0),
|
||||||
image: i.source_ != null ? new DecorationImage(
|
image: i.resourceUrl != null ? new DecorationImage(
|
||||||
fit: BoxFit.contain,
|
fit: BoxFit.cover,
|
||||||
opacity: 0.35,
|
opacity: 0.35,
|
||||||
image: new NetworkImage(
|
image: new NetworkImage(
|
||||||
i.source_!,
|
i.resourceUrl!,
|
||||||
),
|
),
|
||||||
): null,
|
): null,
|
||||||
boxShadow: [
|
boxShadow: [
|
||||||
@ -382,9 +382,9 @@ class _QuizzViewWidget extends State<QuizzViewWidget> {
|
|||||||
child: GridView.builder(
|
child: GridView.builder(
|
||||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
crossAxisCount: 2,
|
crossAxisCount: 2,
|
||||||
mainAxisExtent: kIsWeb ? 75 : 150, // TODO depends on percentage
|
mainAxisExtent: kIsWeb ? 75 : 100, // TODO depends on percentage 150
|
||||||
mainAxisSpacing: kIsWeb ? 75 : 150, // TODO depends on percentage
|
mainAxisSpacing: kIsWeb ? 75 : 45, // TODO depends on percentage
|
||||||
crossAxisSpacing: kIsWeb ? 75 : 150, // TODO depends on percentage
|
crossAxisSpacing: kIsWeb ? 75 : 20, // TODO depends on percentage
|
||||||
),
|
),
|
||||||
itemCount: i.responsesSubDTO!.length,
|
itemCount: i.responsesSubDTO!.length,
|
||||||
itemBuilder: (BuildContext ctx, index) {
|
itemBuilder: (BuildContext ctx, index) {
|
||||||
@ -464,8 +464,8 @@ class _QuizzViewWidget extends State<QuizzViewWidget> {
|
|||||||
},
|
},
|
||||||
child: Icon(
|
child: Icon(
|
||||||
Icons.chevron_right,
|
Icons.chevron_right,
|
||||||
size: kIsWeb ? 100 : 150,
|
size: kIsWeb ? 100 : 95,
|
||||||
color: kMainRed,
|
color: kTestSecondColor,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
@ -480,8 +480,8 @@ class _QuizzViewWidget extends State<QuizzViewWidget> {
|
|||||||
},
|
},
|
||||||
child: Icon(
|
child: Icon(
|
||||||
Icons.chevron_left,
|
Icons.chevron_left,
|
||||||
size: kIsWeb ? 100 : 150,
|
size: kIsWeb ? 100 : 95,
|
||||||
color: kMainRed,
|
color: kTestSecondColor,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
@ -493,7 +493,7 @@ class _QuizzViewWidget extends State<QuizzViewWidget> {
|
|||||||
child: InkWell(
|
child: InkWell(
|
||||||
child: Text(
|
child: Text(
|
||||||
currentIndex.toString()+'/'+quizzDTO.questions!.length.toString(),
|
currentIndex.toString()+'/'+quizzDTO.questions!.length.toString(),
|
||||||
style: TextStyle(fontSize: 30, fontWeight: FontWeight.w500),
|
style: TextStyle(fontSize: 25, fontWeight: FontWeight.w500),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
|||||||
@ -76,11 +76,11 @@ class _ShowReponsesWidget extends State<ShowReponsesWidget> {
|
|||||||
color: kBackgroundLight,
|
color: kBackgroundLight,
|
||||||
shape: BoxShape.rectangle,
|
shape: BoxShape.rectangle,
|
||||||
borderRadius: BorderRadius.circular(20.0),
|
borderRadius: BorderRadius.circular(20.0),
|
||||||
image: i.source_ != null ? new DecorationImage(
|
image: i.resourceUrl != null ? new DecorationImage(
|
||||||
fit: BoxFit.contain,
|
fit: BoxFit.contain,
|
||||||
opacity: 0.35,
|
opacity: 0.35,
|
||||||
image: new NetworkImage(
|
image: new NetworkImage(
|
||||||
i.source_!,
|
i.resourceUrl!,
|
||||||
),
|
),
|
||||||
): null,
|
): null,
|
||||||
boxShadow: [
|
boxShadow: [
|
||||||
|
|||||||
@ -6,19 +6,20 @@ 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/video_viewer.dart';
|
||||||
import 'package:tablet_app/app_context.dart';
|
import 'package:tablet_app/app_context.dart';
|
||||||
import 'package:tablet_app/constants.dart';
|
import 'package:tablet_app/constants.dart';
|
||||||
import 'package:photo_view/photo_view.dart';
|
import 'package:photo_view/photo_view.dart';
|
||||||
|
|
||||||
class SliderViewWidget extends StatefulWidget {
|
class SliderView extends StatefulWidget {
|
||||||
final SectionDTO? section;
|
final SectionDTO? section;
|
||||||
SliderViewWidget({this.section});
|
SliderView({this.section});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_SliderViewWidget createState() => _SliderViewWidget();
|
_SliderView createState() => _SliderView();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _SliderViewWidget extends State<SliderViewWidget> {
|
class _SliderView extends State<SliderView> {
|
||||||
SliderDTO sliderDTO = SliderDTO();
|
SliderDTO sliderDTO = SliderDTO();
|
||||||
CarouselController? sliderController;
|
CarouselController? sliderController;
|
||||||
int currentIndex = 1;
|
int currentIndex = 1;
|
||||||
@ -30,7 +31,7 @@ class _SliderViewWidget extends State<SliderViewWidget> {
|
|||||||
sliderController = CarouselController();
|
sliderController = CarouselController();
|
||||||
sliderDTO = SliderDTO.fromJson(jsonDecode(widget.section!.data!))!;
|
sliderDTO = SliderDTO.fromJson(jsonDecode(widget.section!.data!))!;
|
||||||
|
|
||||||
sliderDTO.images!.sort((a, b) => a.order!.compareTo(b.order!));
|
sliderDTO.contents!.sort((a, b) => a.order!.compareTo(b.order!));
|
||||||
|
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
@ -54,7 +55,7 @@ class _SliderViewWidget extends State<SliderViewWidget> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
children: [
|
children: [
|
||||||
if(sliderDTO.images != null && sliderDTO.images!.length > 0)
|
if(sliderDTO.contents != null && sliderDTO.contents!.length > 0)
|
||||||
CarouselSlider(
|
CarouselSlider(
|
||||||
carouselController: sliderController,
|
carouselController: sliderController,
|
||||||
options: CarouselOptions(
|
options: CarouselOptions(
|
||||||
@ -67,7 +68,7 @@ class _SliderViewWidget extends State<SliderViewWidget> {
|
|||||||
enlargeCenterPage: true,
|
enlargeCenterPage: true,
|
||||||
reverse: false,
|
reverse: false,
|
||||||
),
|
),
|
||||||
items: sliderDTO.images!.map<Widget>((i) {
|
items: sliderDTO.contents!.map<Widget>((i) {
|
||||||
return Builder(
|
return Builder(
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return Container(
|
return Container(
|
||||||
@ -116,18 +117,18 @@ class _SliderViewWidget extends State<SliderViewWidget> {
|
|||||||
child: AspectRatio(
|
child: AspectRatio(
|
||||||
aspectRatio: 16 / 9,
|
aspectRatio: 16 / 9,
|
||||||
child: ClipRect(
|
child: ClipRect(
|
||||||
child: PhotoView(
|
child: VideoViewer(videoUrl: "https://firebasestorage.googleapis.com/v0/b/mymuseum-3b97f.appspot.com/o/All%2024%20Cybertruck%20Accessories%20Revealed!.mp4?alt=media&token=fc178259-10fc-4167-b496-cf7d04aaae5e")/*PhotoView(
|
||||||
imageProvider: new NetworkImage(
|
imageProvider: new NetworkImage(
|
||||||
i.source_!,
|
i.source_!,
|
||||||
),
|
),
|
||||||
minScale: PhotoViewComputedScale.contained * 0.8,
|
minScale: PhotoViewComputedScale.contained * 0.8,
|
||||||
maxScale: PhotoViewComputedScale.contained * 3.0,
|
maxScale: PhotoViewComputedScale.contained * 3.0,
|
||||||
backgroundDecoration: BoxDecoration(
|
backgroundDecoration: BoxDecoration(
|
||||||
color: kBackgroundSecondGrey,
|
color: kBackgroundSecondGrey,
|
||||||
shape: BoxShape.rectangle,
|
shape: BoxShape.rectangle,
|
||||||
borderRadius: BorderRadius.circular(15.0),
|
borderRadius: BorderRadius.circular(15.0),
|
||||||
),
|
),
|
||||||
),
|
),*/
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -190,39 +191,39 @@ class _SliderViewWidget extends State<SliderViewWidget> {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
if(sliderDTO.images != null && sliderDTO.images!.length > 1)
|
if(sliderDTO.contents != null && sliderDTO.contents!.length > 1)
|
||||||
Positioned(
|
Positioned(
|
||||||
top: MediaQuery.of(context).size.height * 0.35,
|
top: MediaQuery.of(context).size.height * 0.35,
|
||||||
right: 60,
|
right: 60,
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
if (sliderDTO.images!.length > 0)
|
if (sliderDTO.contents!.length > 0)
|
||||||
sliderController!.nextPage(duration: new Duration(milliseconds: 500), curve: Curves.fastOutSlowIn);
|
sliderController!.nextPage(duration: new Duration(milliseconds: 500), curve: Curves.fastOutSlowIn);
|
||||||
},
|
},
|
||||||
child: Icon(
|
child: Icon(
|
||||||
Icons.chevron_right,
|
Icons.chevron_right,
|
||||||
size: 150,
|
size: 90,
|
||||||
color: kMainRed,
|
color: Colors.white,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
if(sliderDTO.images != null && sliderDTO.images!.length > 1)
|
if(sliderDTO.contents != null && sliderDTO.contents!.length > 1)
|
||||||
Positioned(
|
Positioned(
|
||||||
top: MediaQuery.of(context).size.height * 0.35,
|
top: MediaQuery.of(context).size.height * 0.35,
|
||||||
left: 60,
|
left: 60,
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
if (sliderDTO.images!.length > 0)
|
if (sliderDTO.contents!.length > 0)
|
||||||
sliderController!.previousPage(duration: new Duration(milliseconds: 500), curve: Curves.fastOutSlowIn);
|
sliderController!.previousPage(duration: new Duration(milliseconds: 500), curve: Curves.fastOutSlowIn);
|
||||||
},
|
},
|
||||||
child: Icon(
|
child: Icon(
|
||||||
Icons.chevron_left,
|
Icons.chevron_left,
|
||||||
size: 150,
|
size: 90,
|
||||||
color: kMainRed,
|
color: Colors.white,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
if(sliderDTO.images != null && sliderDTO.images!.length > 0)
|
if(sliderDTO.contents != null && sliderDTO.contents!.length > 0)
|
||||||
Padding(
|
Padding(
|
||||||
padding: widget.section!.parentId == null ? EdgeInsets.only() : const EdgeInsets.only(left: 15, bottom: 10),
|
padding: widget.section!.parentId == null ? EdgeInsets.only() : const EdgeInsets.only(left: 15, bottom: 10),
|
||||||
child: Align(
|
child: Align(
|
||||||
@ -232,14 +233,14 @@ class _SliderViewWidget extends State<SliderViewWidget> {
|
|||||||
sliderController!.previousPage(duration: new Duration(milliseconds: 500), curve: Curves.fastOutSlowIn);
|
sliderController!.previousPage(duration: new Duration(milliseconds: 500), curve: Curves.fastOutSlowIn);
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
currentIndex.toString()+'/'+sliderDTO.images!.length.toString(),
|
currentIndex.toString()+'/'+sliderDTO.contents!.length.toString(),
|
||||||
style: TextStyle(fontSize: 30, fontWeight: FontWeight.w500),
|
style: TextStyle(fontSize: 25, fontWeight: FontWeight.w500),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if(sliderDTO.images == null || sliderDTO.images!.length == 0)
|
if(sliderDTO.contents == null || sliderDTO.contents!.length == 0)
|
||||||
Center(child: Text("Aucune image à afficher", style: TextStyle(fontSize: kNoneInfoOrIncorrect),))
|
Center(child: Text("Aucun contenu à afficher", style: TextStyle(fontSize: kNoneInfoOrIncorrect),))
|
||||||
// Description
|
// Description
|
||||||
/*Container(
|
/*Container(
|
||||||
height: sliderDTO.images != null && sliderDTO.images.length > 0 ? size.height *0.3 : size.height *0.6,
|
height: sliderDTO.images != null && sliderDTO.images.length > 0 ? size.height *0.3 : size.height *0.6,
|
||||||
|
|||||||
@ -7,15 +7,15 @@ import 'package:tablet_app/constants.dart';
|
|||||||
import 'package:youtube_player_iframe/youtube_player_iframe.dart' as iframe;
|
import 'package:youtube_player_iframe/youtube_player_iframe.dart' as iframe;
|
||||||
import 'package:youtube_player_flutter/youtube_player_flutter.dart';
|
import 'package:youtube_player_flutter/youtube_player_flutter.dart';
|
||||||
|
|
||||||
class VideoViewWidget extends StatefulWidget {
|
class VideoView extends StatefulWidget {
|
||||||
final SectionDTO? section;
|
final SectionDTO? section;
|
||||||
VideoViewWidget({this.section});
|
VideoView({this.section});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_VideoViewWidget createState() => _VideoViewWidget();
|
_VideoView createState() => _VideoView();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _VideoViewWidget extends State<VideoViewWidget> {
|
class _VideoView extends State<VideoView> {
|
||||||
iframe.YoutubePlayer? _videoViewWeb;
|
iframe.YoutubePlayer? _videoViewWeb;
|
||||||
YoutubePlayer? _videoView;
|
YoutubePlayer? _videoView;
|
||||||
VideoDTO? videoDTO;
|
VideoDTO? videoDTO;
|
||||||
|
|||||||
@ -14,10 +14,10 @@ class WebView extends StatefulWidget {
|
|||||||
WebView({this.section});
|
WebView({this.section});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_WebViewWidget createState() => _WebViewWidget();
|
_WebView createState() => _WebView();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _WebViewWidget extends State<WebView> {
|
class _WebView extends State<WebView> {
|
||||||
//final IFrameElement _iframeElement = IFrameElement();
|
//final IFrameElement _iframeElement = IFrameElement();
|
||||||
//WebView _webView;
|
//WebView _webView;
|
||||||
WebDTO webDTO = WebDTO();
|
WebDTO webDTO = WebDTO();
|
||||||
|
|||||||
@ -5,7 +5,7 @@ info:
|
|||||||
description: API Manager Service
|
description: API Manager Service
|
||||||
version: Version Alpha
|
version: Version Alpha
|
||||||
servers:
|
servers:
|
||||||
- url: http://localhost:5000
|
- url: https://api.myinfomate.be
|
||||||
paths:
|
paths:
|
||||||
/api/Configuration:
|
/api/Configuration:
|
||||||
get:
|
get:
|
||||||
@ -2400,6 +2400,12 @@ components:
|
|||||||
nullable: true
|
nullable: true
|
||||||
oneOf:
|
oneOf:
|
||||||
- $ref: '#/components/schemas/ContentDTO'
|
- $ref: '#/components/schemas/ContentDTO'
|
||||||
|
rows:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
cols:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
AgendaDTO:
|
AgendaDTO:
|
||||||
type: object
|
type: object
|
||||||
additionalProperties: false
|
additionalProperties: false
|
||||||
|
|||||||
@ -17,20 +17,20 @@ const kBackgroundLight = Color(0xfff3f3f3);
|
|||||||
|
|
||||||
const List<String> languages = ["FR", "NL", "EN", "DE", "IT", "ES", "PL", "CN", "AR", "UK"]; // hmmmm depends on config..
|
const List<String> languages = ["FR", "NL", "EN", "DE", "IT", "ES", "PL", "CN", "AR", "UK"]; // hmmmm depends on config..
|
||||||
|
|
||||||
const kTitleSize = 40.0;
|
const kTitleSize = 32.0;
|
||||||
const kDescriptionSize = 25.0;
|
const kDescriptionSize = 15.0;
|
||||||
|
|
||||||
const kSectionTitleDetailSize = 50.0;
|
const kSectionTitleDetailSize = 30.0;
|
||||||
const kSectionDescriptionDetailSize = 35.0;
|
const kSectionDescriptionDetailSize = 18.0;
|
||||||
|
|
||||||
const kMenuTitleDetailSize = 45.0;
|
const kMenuTitleDetailSize = 30.0;
|
||||||
const kMenuDescriptionDetailSize = 28.0;
|
const kMenuDescriptionDetailSize = 15.0;
|
||||||
|
|
||||||
// WEB
|
// WEB
|
||||||
const kWebMenuTitleDetailSize = 30.0;
|
const kWebMenuTitleDetailSize = 30.0;
|
||||||
const kWebMenuDescriptionDetailSize = 14.0;
|
const kWebMenuDescriptionDetailSize = 14.0;
|
||||||
const kWebSectionTitleDetailSize = 35.0;
|
const kWebSectionTitleDetailSize = 30.0;
|
||||||
const kWebSectionDescriptionDetailSize = 20.0;
|
const kWebSectionDescriptionDetailSize = 15.0;
|
||||||
|
|
||||||
const kWebTitleSize = 30.0;
|
const kWebTitleSize = 30.0;
|
||||||
const kWebDescriptionSize = 14.0;
|
const kWebDescriptionSize = 14.0;
|
||||||
|
|||||||
@ -45,7 +45,7 @@ void main() async {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
print("NO LOCAL DB !");
|
print("NO LOCAL DB !");
|
||||||
localContext = TabletAppContext(host: "https://api.mymuseum.be");
|
localContext = TabletAppContext(host: "https://api.myinfomate.be");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(kIsWeb) {
|
if(kIsWeb) {
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
import 'package:manager_api/api.dart';
|
import 'package:manager_api/api.dart';
|
||||||
```
|
```
|
||||||
|
|
||||||
All URIs are relative to *http://localhost:5000*
|
All URIs are relative to *https://api.myinfomate.be*
|
||||||
|
|
||||||
Method | HTTP request | Description
|
Method | HTTP request | Description
|
||||||
------------- | ------------- | -------------
|
------------- | ------------- | -------------
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
import 'package:manager_api/api.dart';
|
import 'package:manager_api/api.dart';
|
||||||
```
|
```
|
||||||
|
|
||||||
All URIs are relative to *http://localhost:5000*
|
All URIs are relative to *https://api.myinfomate.be*
|
||||||
|
|
||||||
Method | HTTP request | Description
|
Method | HTTP request | Description
|
||||||
------------- | ------------- | -------------
|
------------- | ------------- | -------------
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
import 'package:manager_api/api.dart';
|
import 'package:manager_api/api.dart';
|
||||||
```
|
```
|
||||||
|
|
||||||
All URIs are relative to *http://localhost:5000*
|
All URIs are relative to *https://api.myinfomate.be*
|
||||||
|
|
||||||
Method | HTTP request | Description
|
Method | HTTP request | Description
|
||||||
------------- | ------------- | -------------
|
------------- | ------------- | -------------
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
import 'package:manager_api/api.dart';
|
import 'package:manager_api/api.dart';
|
||||||
```
|
```
|
||||||
|
|
||||||
All URIs are relative to *http://localhost:5000*
|
All URIs are relative to *https://api.myinfomate.be*
|
||||||
|
|
||||||
Method | HTTP request | Description
|
Method | HTTP request | Description
|
||||||
------------- | ------------- | -------------
|
------------- | ------------- | -------------
|
||||||
|
|||||||
@ -11,6 +11,8 @@ Name | Type | Description | Notes
|
|||||||
**messageDebut** | [**List<TranslationAndResourceDTO>**](TranslationAndResourceDTO.md) | | [optional] [default to const []]
|
**messageDebut** | [**List<TranslationAndResourceDTO>**](TranslationAndResourceDTO.md) | | [optional] [default to const []]
|
||||||
**messageFin** | [**List<TranslationAndResourceDTO>**](TranslationAndResourceDTO.md) | | [optional] [default to const []]
|
**messageFin** | [**List<TranslationAndResourceDTO>**](TranslationAndResourceDTO.md) | | [optional] [default to const []]
|
||||||
**image** | [**PuzzleDTOImage**](PuzzleDTOImage.md) | | [optional]
|
**image** | [**PuzzleDTOImage**](PuzzleDTOImage.md) | | [optional]
|
||||||
|
**rows** | **int** | | [optional]
|
||||||
|
**cols** | **int** | | [optional]
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
import 'package:manager_api/api.dart';
|
import 'package:manager_api/api.dart';
|
||||||
```
|
```
|
||||||
|
|
||||||
All URIs are relative to *http://localhost:5000*
|
All URIs are relative to *https://api.myinfomate.be*
|
||||||
|
|
||||||
Method | HTTP request | Description
|
Method | HTTP request | Description
|
||||||
------------- | ------------- | -------------
|
------------- | ------------- | -------------
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
import 'package:manager_api/api.dart';
|
import 'package:manager_api/api.dart';
|
||||||
```
|
```
|
||||||
|
|
||||||
All URIs are relative to *http://localhost:5000*
|
All URIs are relative to *https://api.myinfomate.be*
|
||||||
|
|
||||||
Method | HTTP request | Description
|
Method | HTTP request | Description
|
||||||
------------- | ------------- | -------------
|
------------- | ------------- | -------------
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
import 'package:manager_api/api.dart';
|
import 'package:manager_api/api.dart';
|
||||||
```
|
```
|
||||||
|
|
||||||
All URIs are relative to *http://localhost:5000*
|
All URIs are relative to *https://api.myinfomate.be*
|
||||||
|
|
||||||
Method | HTTP request | Description
|
Method | HTTP request | Description
|
||||||
------------- | ------------- | -------------
|
------------- | ------------- | -------------
|
||||||
|
|||||||
@ -11,7 +11,7 @@
|
|||||||
part of openapi.api;
|
part of openapi.api;
|
||||||
|
|
||||||
class ApiClient {
|
class ApiClient {
|
||||||
ApiClient({this.basePath = 'http://localhost:5000', this.authentication,});
|
ApiClient({this.basePath = 'https://api.myinfomate.be', this.authentication,});
|
||||||
|
|
||||||
final String basePath;
|
final String basePath;
|
||||||
final Authentication? authentication;
|
final Authentication? authentication;
|
||||||
|
|||||||
@ -16,6 +16,8 @@ class PuzzleDTO {
|
|||||||
this.messageDebut = const [],
|
this.messageDebut = const [],
|
||||||
this.messageFin = const [],
|
this.messageFin = const [],
|
||||||
this.image,
|
this.image,
|
||||||
|
this.rows,
|
||||||
|
this.cols,
|
||||||
});
|
});
|
||||||
|
|
||||||
List<TranslationAndResourceDTO>? messageDebut;
|
List<TranslationAndResourceDTO>? messageDebut;
|
||||||
@ -24,21 +26,41 @@ class PuzzleDTO {
|
|||||||
|
|
||||||
PuzzleDTOImage? image;
|
PuzzleDTOImage? image;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Please note: This property should have been non-nullable! Since the specification file
|
||||||
|
/// does not include a default value (using the "default:" property), however, the generated
|
||||||
|
/// source code must fall back to having a nullable type.
|
||||||
|
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||||
|
///
|
||||||
|
int? rows;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Please note: This property should have been non-nullable! Since the specification file
|
||||||
|
/// does not include a default value (using the "default:" property), however, the generated
|
||||||
|
/// source code must fall back to having a nullable type.
|
||||||
|
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||||
|
///
|
||||||
|
int? cols;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) => identical(this, other) || other is PuzzleDTO &&
|
bool operator ==(Object other) => identical(this, other) || other is PuzzleDTO &&
|
||||||
other.messageDebut == messageDebut &&
|
other.messageDebut == messageDebut &&
|
||||||
other.messageFin == messageFin &&
|
other.messageFin == messageFin &&
|
||||||
other.image == image;
|
other.image == image &&
|
||||||
|
other.rows == rows &&
|
||||||
|
other.cols == cols;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode =>
|
int get hashCode =>
|
||||||
// ignore: unnecessary_parenthesis
|
// ignore: unnecessary_parenthesis
|
||||||
(messageDebut == null ? 0 : messageDebut!.hashCode) +
|
(messageDebut == null ? 0 : messageDebut!.hashCode) +
|
||||||
(messageFin == null ? 0 : messageFin!.hashCode) +
|
(messageFin == null ? 0 : messageFin!.hashCode) +
|
||||||
(image == null ? 0 : image!.hashCode);
|
(image == null ? 0 : image!.hashCode) +
|
||||||
|
(rows == null ? 0 : rows!.hashCode) +
|
||||||
|
(cols == null ? 0 : cols!.hashCode);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() => 'PuzzleDTO[messageDebut=$messageDebut, messageFin=$messageFin, image=$image]';
|
String toString() => 'PuzzleDTO[messageDebut=$messageDebut, messageFin=$messageFin, image=$image, rows=$rows, cols=$cols]';
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
final json = <String, dynamic>{};
|
final json = <String, dynamic>{};
|
||||||
@ -57,6 +79,16 @@ class PuzzleDTO {
|
|||||||
} else {
|
} else {
|
||||||
json[r'image'] = null;
|
json[r'image'] = null;
|
||||||
}
|
}
|
||||||
|
if (this.rows != null) {
|
||||||
|
json[r'rows'] = this.rows;
|
||||||
|
} else {
|
||||||
|
json[r'rows'] = null;
|
||||||
|
}
|
||||||
|
if (this.cols != null) {
|
||||||
|
json[r'cols'] = this.cols;
|
||||||
|
} else {
|
||||||
|
json[r'cols'] = null;
|
||||||
|
}
|
||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,6 +114,8 @@ class PuzzleDTO {
|
|||||||
messageDebut: TranslationAndResourceDTO.listFromJson(json[r'messageDebut']),
|
messageDebut: TranslationAndResourceDTO.listFromJson(json[r'messageDebut']),
|
||||||
messageFin: TranslationAndResourceDTO.listFromJson(json[r'messageFin']),
|
messageFin: TranslationAndResourceDTO.listFromJson(json[r'messageFin']),
|
||||||
image: PuzzleDTOImage.fromJson(json[r'image']),
|
image: PuzzleDTOImage.fromJson(json[r'image']),
|
||||||
|
rows: mapValueOfType<int>(json, r'rows'),
|
||||||
|
cols: mapValueOfType<int>(json, r'cols'),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@ -23,28 +23,28 @@ class ResourceType {
|
|||||||
|
|
||||||
int toJson() => value;
|
int toJson() => value;
|
||||||
|
|
||||||
static const image = ResourceType._(0);
|
static const Image = ResourceType._(0);
|
||||||
static const video = ResourceType._(1);
|
static const Video = ResourceType._(1);
|
||||||
static const imageUrl = ResourceType._(2);
|
static const ImageUrl = ResourceType._(2);
|
||||||
static const videoUrl = ResourceType._(3);
|
static const VideoUrl = ResourceType._(3);
|
||||||
static const audio = ResourceType._(4);
|
static const Audio = ResourceType._(4);
|
||||||
static const PDF = ResourceType._(5);
|
static const Pdf = ResourceType._(5);
|
||||||
static const JSON = ResourceType._(6);
|
static const Json = ResourceType._(6);
|
||||||
|
|
||||||
/// List of all possible values in this [enum][ResourceType].
|
/// List of all possible values in this [enum][ResourceType].
|
||||||
static const values = <ResourceType>[
|
static const values = <ResourceType>[
|
||||||
image,
|
Image,
|
||||||
video,
|
Video,
|
||||||
imageUrl,
|
ImageUrl,
|
||||||
videoUrl,
|
VideoUrl,
|
||||||
audio,
|
Audio,
|
||||||
PDF,
|
Pdf,
|
||||||
JSON
|
Json
|
||||||
];
|
];
|
||||||
|
|
||||||
static ResourceType? fromJson(dynamic value) => ResourceTypeTypeTransformer().decode(value);
|
static ResourceType? fromJson(dynamic value) => ResourceTypeTypeTransformer().decode(value);
|
||||||
|
|
||||||
static List<ResourceType> listFromJson(dynamic json, {bool growable = false,}) {
|
static List<ResourceType>? listFromJson(dynamic json, {bool growable = false,}) {
|
||||||
final result = <ResourceType>[];
|
final result = <ResourceType>[];
|
||||||
if (json is List && json.isNotEmpty) {
|
if (json is List && json.isNotEmpty) {
|
||||||
for (final row in json) {
|
for (final row in json) {
|
||||||
@ -77,18 +77,36 @@ class ResourceTypeTypeTransformer {
|
|||||||
/// and users are still using an old app with the old code.
|
/// and users are still using an old app with the old code.
|
||||||
ResourceType? decode(dynamic data, {bool allowNull = true}) {
|
ResourceType? decode(dynamic data, {bool allowNull = true}) {
|
||||||
if (data != null) {
|
if (data != null) {
|
||||||
switch (data.toString()) {
|
if(data.runtimeType == String) {
|
||||||
case r'Image': return ResourceType.image;
|
switch (data.toString()) {
|
||||||
case r'Video': return ResourceType.video;
|
case "Image": return ResourceType.Image;
|
||||||
case r'ImageUrl': return ResourceType.imageUrl;
|
case "Video": return ResourceType.Video;
|
||||||
case r'VideoUrl': return ResourceType.videoUrl;
|
case "ImageUrl": return ResourceType.ImageUrl;
|
||||||
case r'Audio': return ResourceType.audio;
|
case "VideoUrl": return ResourceType.VideoUrl;
|
||||||
case r'PDF': return ResourceType.PDF;
|
case "Audio": return ResourceType.Audio;
|
||||||
case r'JSON': return ResourceType.JSON;
|
case "PDF": return ResourceType.Pdf;
|
||||||
default:
|
case "JSON": return ResourceType.Json;
|
||||||
if (!allowNull) {
|
default:
|
||||||
throw ArgumentError('Unknown enum value to decode: $data');
|
if (!allowNull) {
|
||||||
|
throw ArgumentError('Unknown enum value to decode: $data');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(data.runtimeType == int) {
|
||||||
|
switch (data) {
|
||||||
|
case 0: return ResourceType.Image;
|
||||||
|
case 1: return ResourceType.Video;
|
||||||
|
case 2: return ResourceType.ImageUrl;
|
||||||
|
case 3: return ResourceType.VideoUrl;
|
||||||
|
case 4: return ResourceType.Audio;
|
||||||
|
case 5: return ResourceType.Pdf;
|
||||||
|
case 6: return ResourceType.Json;
|
||||||
|
default:
|
||||||
|
if (!allowNull) {
|
||||||
|
throw ArgumentError('Unknown enum value to decode: $data');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user