mirror of
https://bitbucket.org/FransoletThomas/tablet-app.git
synced 2025-12-06 16:41:19 +00:00
Download resources at start + use local resources (PDF) + clean code
This commit is contained in:
parent
e2beefb0be
commit
bda99e384d
@ -1,6 +1,11 @@
|
|||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:cached_network_image/cached_network_image.dart';
|
import 'package:cached_network_image/cached_network_image.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:manager_api/api.dart';
|
||||||
|
import 'package:path_provider/path_provider.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:tablet_app/Components/cached_custom_resource.dart';
|
||||||
import 'package:tablet_app/Models/tabletContext.dart';
|
import 'package:tablet_app/Models/tabletContext.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';
|
||||||
@ -54,11 +59,29 @@ class _LoadingCommonState extends State<LoadingCommon> with TickerProviderStateM
|
|||||||
turns: Tween(begin: 0.0, end: 3.0).animate(_controller!),
|
turns: Tween(begin: 0.0, end: 3.0).animate(_controller!),
|
||||||
child: tabletAppContext.configuration != null && tabletAppContext.configuration!.loaderImageUrl != null ?
|
child: tabletAppContext.configuration != null && tabletAppContext.configuration!.loaderImageUrl != null ?
|
||||||
//Image.network(tabletAppContext.configuration!.loaderImageUrl!)
|
//Image.network(tabletAppContext.configuration!.loaderImageUrl!)
|
||||||
CachedNetworkImage(
|
// TODO Replace by CustomCacheResource..
|
||||||
|
FutureBuilder<File?>(
|
||||||
|
future: _checkIfLocalResourceExists(tabletAppContext, tabletAppContext.configuration!.loaderImageId!),
|
||||||
|
builder: (context, snapshot) {
|
||||||
|
if (snapshot.connectionState == ConnectionState.waiting) {
|
||||||
|
// Loader ou indicateur de chargement pendant la vérification
|
||||||
|
return CircularProgressIndicator();
|
||||||
|
} else if (snapshot.hasError || snapshot.data == null) {
|
||||||
|
// Si la ressource locale n'existe pas ou s'il y a une erreur
|
||||||
|
print("not a local loader succck");
|
||||||
|
return CachedNetworkImage(
|
||||||
imageUrl: tabletAppContext.configuration!.loaderImageUrl!,
|
imageUrl: tabletAppContext.configuration!.loaderImageUrl!,
|
||||||
progressIndicatorBuilder: (context, url, downloadProgress) =>
|
progressIndicatorBuilder: (context, url, downloadProgress) =>
|
||||||
CircularProgressIndicator(value: downloadProgress.progress, color: primaryColor),
|
CircularProgressIndicator(value: downloadProgress.progress, color: primaryColor),
|
||||||
errorWidget: (context, url, error) => Icon(Icons.error),
|
errorWidget: (context, url, error) => Icon(Icons.error),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
print("Its a local loaaader yeah");
|
||||||
|
return Image.file(
|
||||||
|
snapshot.data!,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
)
|
)
|
||||||
: Icon(Icons.museum_outlined, color: kTestSecondColor, size: size.height*0.1),
|
: Icon(Icons.museum_outlined, color: kTestSecondColor, size: size.height*0.1),
|
||||||
),
|
),
|
||||||
@ -67,4 +90,23 @@ class _LoadingCommonState extends State<LoadingCommon> with TickerProviderStateM
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<File?> _checkIfLocalResourceExists(TabletAppContext tabletAppContext, String resourceId) async {
|
||||||
|
try {
|
||||||
|
Directory? appDocumentsDirectory = await getDownloadsDirectory();
|
||||||
|
String localPath = appDocumentsDirectory!.path;
|
||||||
|
Directory configurationDirectory = Directory('$localPath/${tabletAppContext.configuration!.id}');
|
||||||
|
List<FileSystemEntity> fileList = configurationDirectory.listSync();
|
||||||
|
|
||||||
|
if(fileList.any((fileL) => fileL.uri.pathSegments.last.contains(resourceId))) {
|
||||||
|
File file = File(fileList.firstWhere((fileL) => fileL.uri.pathSegments.last.contains(resourceId)).path);
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
} catch(e) {
|
||||||
|
print("ERROR _checkIfLocalResourceExists CachedCustomResource");
|
||||||
|
print(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -13,13 +13,12 @@ class ImageCustomProvider {
|
|||||||
Directory configurationDirectory = Directory('${tabletAppContext.localPath!}/${tabletAppContext.configuration!.id!}');
|
Directory configurationDirectory = Directory('${tabletAppContext.localPath!}/${tabletAppContext.configuration!.id!}');
|
||||||
List<FileSystemEntity> fileList = configurationDirectory.listSync();
|
List<FileSystemEntity> fileList = configurationDirectory.listSync();
|
||||||
|
|
||||||
print(fileList);
|
if(fileList.any((fileL) => fileL.uri.pathSegments.last.contains(imageId))) {
|
||||||
|
File file = File(fileList.firstWhere((fileL) => fileL.uri.pathSegments.last.contains(imageId)).path);
|
||||||
if (fileList.isNotEmpty) {
|
|
||||||
File file = File(fileList.first.path);
|
|
||||||
print("FILE EXISTT");
|
print("FILE EXISTT");
|
||||||
return FileImage(file);
|
return FileImage(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
print("Error getImageProvider");
|
print("Error getImageProvider");
|
||||||
|
|||||||
@ -51,6 +51,10 @@ class _MainViewWidget extends State<MainViewWidget> {
|
|||||||
late Color backgroundColor;
|
late Color backgroundColor;
|
||||||
int rowCount = 4;
|
int rowCount = 4;
|
||||||
|
|
||||||
|
List<SectionDTO>? sectionsLocal;
|
||||||
|
bool isInit = true; // Use to make it faster and to load resource at init
|
||||||
|
bool isDialogOpen = false;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
final appContext = Provider.of<AppContext>(context, listen: false);
|
final appContext = Provider.of<AppContext>(context, listen: false);
|
||||||
@ -58,6 +62,7 @@ class _MainViewWidget extends State<MainViewWidget> {
|
|||||||
if(configurationDTO.isHour != null && configurationDTO.isHour!) {
|
if(configurationDTO.isHour != null && configurationDTO.isHour!) {
|
||||||
Timer.periodic(Duration(seconds: 1), (Timer t) => _getTime(currentHourDate));
|
Timer.periodic(Duration(seconds: 1), (Timer t) => _getTime(currentHourDate));
|
||||||
}
|
}
|
||||||
|
print("Init state helloowww");
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -295,8 +300,8 @@ class _MainViewWidget extends State<MainViewWidget> {
|
|||||||
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: isInit ? FutureBuilder(
|
||||||
future: getSections(appContext),
|
future: getSections(size, 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) {
|
||||||
@ -304,20 +309,145 @@ class _MainViewWidget extends State<MainViewWidget> {
|
|||||||
return Text("");
|
return Text("");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
return getGridSections(appContext);
|
||||||
|
}
|
||||||
|
} else if (snapshot.connectionState == ConnectionState.none) {
|
||||||
|
return Text("No data");
|
||||||
|
} else {
|
||||||
|
return Center(
|
||||||
|
child: Container(
|
||||||
|
child: LoadingCommon()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
) : getGridSections(appContext),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if(configurationDTO.weatherCity != null)
|
||||||
|
Positioned(
|
||||||
|
bottom: 0,
|
||||||
|
left: 0,
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: Text('Weather - ' + configurationDTO.weatherCity!, style: TextStyle(fontSize: 15, color: textColor))
|
||||||
|
))
|
||||||
|
]),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
backgroundColor = tabletAppContext.configuration != null ? new Color(int.parse(appContext.getContext().configuration.secondaryColor.split('(0x')[1].split(')')[0], radix: 16)) : Colors.white;
|
||||||
|
|
||||||
|
TabletAppContext? localContext = await DatabaseHelper.instance.getData();
|
||||||
|
if (localContext != null) { // Check if sql DB exist
|
||||||
|
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(Size size, dynamic appContext) async {
|
||||||
|
TabletAppContext tabletAppContext = await appContext.getContext();
|
||||||
|
|
||||||
|
print("getSectionsgetSectionsgetSectionsgetSections");
|
||||||
|
|
||||||
|
// DIALOG HERE
|
||||||
|
if(!isDialogOpen) {
|
||||||
|
isDialogOpen = true;
|
||||||
|
|
||||||
|
var result = await showDialog(
|
||||||
|
builder: (BuildContext dialogContext) => AlertDialog(
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(20.0))
|
||||||
|
),
|
||||||
|
content: Container(
|
||||||
|
width: 400,
|
||||||
|
height: 200,
|
||||||
|
child: DownloadConfigurationWidget(),
|
||||||
|
),
|
||||||
|
actions: <Widget>[],
|
||||||
|
), context: context
|
||||||
|
);
|
||||||
|
print("COUCOUCOUCOU");
|
||||||
|
print(result);
|
||||||
|
|
||||||
|
isDialogOpen = false;
|
||||||
|
} else {
|
||||||
|
print("ALREADY OPEN LAAAA");
|
||||||
|
}
|
||||||
|
|
||||||
|
//await getCurrentConfiguration(appContext);
|
||||||
|
|
||||||
|
print(sectionsLocal);
|
||||||
|
|
||||||
|
if(isInit) {
|
||||||
|
try {
|
||||||
|
List<SectionDTO>? sections = await tabletAppContext.clientAPI!.sectionApi!.sectionGetFromConfiguration(tabletAppContext.configuration!.id!);
|
||||||
|
sections!.sort((a, b) => a.order!.compareTo(b.order!));
|
||||||
|
sectionsLocal = sections;
|
||||||
|
isInit = false;
|
||||||
|
return sections;
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
print("IN CATCH");
|
||||||
|
Navigator.pushAndRemoveUntil(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (context) {
|
||||||
|
return ConfigViewWidget();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
(Route<dynamic> route) => false // For pushAndRemoveUntil
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sectionsLocal;
|
||||||
|
}
|
||||||
|
|
||||||
|
getGridSections(AppContext appContext) {
|
||||||
|
if(sectionsLocal != null) {
|
||||||
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: sectionsLocal!.length,
|
||||||
itemBuilder: (BuildContext context, int index) {
|
itemBuilder: (BuildContext context, int index) {
|
||||||
return InkWell(
|
return InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
sectionSelected = snapshot.data[index];
|
sectionSelected = sectionsLocal![index];
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
decoration: boxDecoration(appContext, snapshot.data[index], false),
|
decoration: boxDecoration(appContext, sectionsLocal![index], false),
|
||||||
padding: const EdgeInsets.all(25),
|
padding: const EdgeInsets.all(25),
|
||||||
margin: EdgeInsets.symmetric(vertical: 25, horizontal: 25),
|
margin: EdgeInsets.symmetric(vertical: 25, horizontal: 25),
|
||||||
child: Align(
|
child: Align(
|
||||||
@ -335,7 +465,7 @@ class _MainViewWidget extends State<MainViewWidget> {
|
|||||||
child: Align(
|
child: Align(
|
||||||
alignment: Alignment.centerRight,
|
alignment: Alignment.centerRight,
|
||||||
child: HtmlWidget(
|
child: HtmlWidget(
|
||||||
snapshot.data[index].title.firstWhere((translation) => translation.language == appContext.getContext().language).value,
|
sectionsLocal![index].title!.firstWhere((translation) => translation.language == appContext.getContext().language).value ?? "",
|
||||||
customStylesBuilder: (element) {
|
customStylesBuilder: (element) {
|
||||||
return {'text-align': 'right'};
|
return {'text-align': 'right'};
|
||||||
},
|
},
|
||||||
@ -351,7 +481,7 @@ class _MainViewWidget extends State<MainViewWidget> {
|
|||||||
child: Align(
|
child: Align(
|
||||||
alignment: Alignment.centerRight,
|
alignment: Alignment.centerRight,
|
||||||
child: HtmlWidget(
|
child: HtmlWidget(
|
||||||
snapshot.data[index].description.firstWhere((translation) => translation.language == appContext.getContext().language).value,
|
sectionsLocal![index].description!.firstWhere((translation) => translation.language == appContext.getContext().language).value ?? "",
|
||||||
customStylesBuilder: (element) {
|
customStylesBuilder: (element) {
|
||||||
return {'text-align': 'right'};
|
return {'text-align': 'right'};
|
||||||
},
|
},
|
||||||
@ -400,116 +530,12 @@ class _MainViewWidget extends State<MainViewWidget> {
|
|||||||
}
|
}
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
|
||||||
} else if (snapshot.connectionState == ConnectionState.none) {
|
|
||||||
return Text("No data");
|
|
||||||
} else {
|
} else {
|
||||||
return Center(
|
Center(
|
||||||
child: Container(
|
child: Text("Aucune section à afficher", style: TextStyle(fontSize: kNoneInfoOrIncorrect)),
|
||||||
child: LoadingCommon()
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if(configurationDTO.weatherCity != null)
|
|
||||||
Positioned(
|
|
||||||
bottom: 0,
|
|
||||||
left: 0,
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.all(8.0),
|
|
||||||
child: Text('Weather - ' + configurationDTO.weatherCity!, style: TextStyle(fontSize: 15, color: textColor))
|
|
||||||
))
|
|
||||||
]),
|
|
||||||
),
|
|
||||||
floatingActionButton: InkWell(
|
|
||||||
onTap: () async {
|
|
||||||
var result = await showDialog(
|
|
||||||
builder: (BuildContext dialogContext) => AlertDialog(
|
|
||||||
shape: RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.all(Radius.circular(20.0))
|
|
||||||
),
|
|
||||||
content: Container(
|
|
||||||
width: size.width *0.5,
|
|
||||||
height: size.height *0.5,
|
|
||||||
child: DownloadConfigurationWidget(),
|
|
||||||
),
|
|
||||||
actions: <Widget>[],
|
|
||||||
), context: context
|
|
||||||
);
|
|
||||||
|
|
||||||
print("RESULLLLT");
|
|
||||||
print(result);
|
|
||||||
},
|
|
||||||
child: Container(
|
|
||||||
width: 150,
|
|
||||||
height: 150,
|
|
||||||
color: Colors.red,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
backgroundColor = tabletAppContext.configuration != null ? new Color(int.parse(appContext.getContext().configuration.secondaryColor.split('(0x')[1].split(')')[0], radix: 16)) : Colors.white;
|
|
||||||
|
|
||||||
TabletAppContext? localContext = await DatabaseHelper.instance.getData();
|
|
||||||
if (localContext != null) { // Check if sql DB exist
|
|
||||||
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 {
|
|
||||||
TabletAppContext tabletAppContext = await appContext.getContext();
|
|
||||||
|
|
||||||
await getCurrentConfiguration(appContext);
|
|
||||||
|
|
||||||
try {
|
|
||||||
List<SectionDTO>? sections = await tabletAppContext.clientAPI!.sectionApi!.sectionGetFromConfiguration(tabletAppContext.configuration!.id!);
|
|
||||||
sections!.sort((a, b) => a.order!.compareTo(b.order!));
|
|
||||||
return sections;
|
|
||||||
} catch (e) {
|
|
||||||
print(e);
|
|
||||||
print("IN CATCH");
|
|
||||||
Navigator.pushAndRemoveUntil(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(
|
|
||||||
builder: (context) {
|
|
||||||
return ConfigViewWidget();
|
|
||||||
},
|
|
||||||
),
|
|
||||||
(Route<dynamic> route) => false // For pushAndRemoveUntil
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -13,6 +13,7 @@ import 'package:provider/provider.dart';
|
|||||||
import 'package:tablet_app/Components/loading_common.dart';
|
import 'package:tablet_app/Components/loading_common.dart';
|
||||||
import 'package:tablet_app/Models/tabletContext.dart';
|
import 'package:tablet_app/Models/tabletContext.dart';
|
||||||
import 'package:tablet_app/app_context.dart';
|
import 'package:tablet_app/app_context.dart';
|
||||||
|
import 'package:tablet_app/constants.dart';
|
||||||
|
|
||||||
|
|
||||||
class PDFViewWidget extends StatefulWidget {
|
class PDFViewWidget extends StatefulWidget {
|
||||||
@ -160,7 +161,7 @@ class _PDFViewWidget extends State<PDFViewWidget> {
|
|||||||
}
|
}
|
||||||
),
|
),
|
||||||
) :
|
) :
|
||||||
Center(child: Text("Le PDF ne peut pas être affiché, il n'existe pas"));
|
Center(child: Text("Le PDF ne peut pas être affiché, il n'existe pas", style: TextStyle(fontSize: kNoneInfoOrIncorrect)));
|
||||||
}
|
}
|
||||||
} //_webView
|
} //_webView
|
||||||
|
|
||||||
|
|||||||
@ -10,6 +10,7 @@ import 'package:tablet_app/Components/loading_common.dart';
|
|||||||
import 'package:tablet_app/Models/tabletContext.dart';
|
import 'package:tablet_app/Models/tabletContext.dart';
|
||||||
import 'package:tablet_app/Screens/Puzzle/message_dialog.dart';
|
import 'package:tablet_app/Screens/Puzzle/message_dialog.dart';
|
||||||
import 'package:tablet_app/app_context.dart';
|
import 'package:tablet_app/app_context.dart';
|
||||||
|
import 'package:tablet_app/constants.dart';
|
||||||
import 'puzzle_piece.dart';
|
import 'puzzle_piece.dart';
|
||||||
|
|
||||||
const IMAGE_PATH = 'image_path';
|
const IMAGE_PATH = 'image_path';
|
||||||
@ -61,6 +62,10 @@ class _PuzzleView extends State<PuzzleView> {
|
|||||||
fit: BoxFit.fill,
|
fit: BoxFit.fill,
|
||||||
errorWidget: (context, url, error) => Icon(Icons.error),
|
errorWidget: (context, url, error) => Icon(Icons.error),
|
||||||
));
|
));
|
||||||
|
} else {
|
||||||
|
setState(() {
|
||||||
|
isSplittingImage = false;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -204,8 +209,8 @@ class _PuzzleView extends State<PuzzleView> {
|
|||||||
key: _widgetKey,
|
key: _widgetKey,
|
||||||
padding: const EdgeInsets.all(10.0),
|
padding: const EdgeInsets.all(10.0),
|
||||||
child: isSplittingImage ? Center(child: LoadingCommon()) :
|
child: isSplittingImage ? Center(child: LoadingCommon()) :
|
||||||
puzzleDTO.image!.resourceUrl == null || realWidgetSize == null
|
puzzleDTO.image == null || puzzleDTO.image!.resourceUrl == null || realWidgetSize == null
|
||||||
? Center(child: Text("Invalid image"))
|
? Center(child: Text("Aucune image à afficher", style: TextStyle(fontSize: kNoneInfoOrIncorrect)))
|
||||||
: Center(
|
: Center(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
|||||||
@ -221,7 +221,7 @@ class _SliderView extends State<SliderView> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
if(sliderDTO.contents == null || sliderDTO.contents!.length == 0)
|
if(sliderDTO.contents == null || sliderDTO.contents!.length == 0)
|
||||||
Center(child: Text("Aucun contenu à 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,
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import 'dart:ui' as ui;
|
|||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:manager_api/api.dart';
|
import 'package:manager_api/api.dart';
|
||||||
|
import 'package:tablet_app/constants.dart';
|
||||||
import 'package:webview_flutter/webview_flutter.dart';
|
import 'package:webview_flutter/webview_flutter.dart';
|
||||||
import 'package:webview_flutter_platform_interface/webview_flutter_platform_interface.dart';
|
import 'package:webview_flutter_platform_interface/webview_flutter_platform_interface.dart';
|
||||||
//import 'package:webview_flutter_web/webview_flutter_web.dart';
|
//import 'package:webview_flutter_web/webview_flutter_web.dart';
|
||||||
@ -30,6 +31,7 @@ class _WebView extends State<WebView> {
|
|||||||
webDTO = WebDTO.fromJson(jsonDecode(widget.section!.data!))!;
|
webDTO = WebDTO.fromJson(jsonDecode(widget.section!.data!))!;
|
||||||
print(webDTO);
|
print(webDTO);
|
||||||
|
|
||||||
|
|
||||||
if(kIsWeb) {
|
if(kIsWeb) {
|
||||||
/*_iframeElement.src = webDTO.source_!;
|
/*_iframeElement.src = webDTO.source_!;
|
||||||
_iframeElement.style.border = 'none';
|
_iframeElement.style.border = 'none';
|
||||||
@ -40,6 +42,9 @@ class _WebView extends State<WebView> {
|
|||||||
(int viewId) => _iframeElement,
|
(int viewId) => _iframeElement,
|
||||||
);*/
|
);*/
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
if(webDTO.source_ != null && webDTO.source_!.length > 0) {
|
||||||
|
try {
|
||||||
controller = WebViewController()
|
controller = WebViewController()
|
||||||
..setJavaScriptMode(JavaScriptMode.unrestricted)
|
..setJavaScriptMode(JavaScriptMode.unrestricted)
|
||||||
..setBackgroundColor(const Color(0x00000000))
|
..setBackgroundColor(const Color(0x00000000))
|
||||||
@ -64,6 +69,10 @@ class _WebView extends State<WebView> {
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
..loadRequest(Uri.parse(webDTO.source_!));
|
..loadRequest(Uri.parse(webDTO.source_!));
|
||||||
|
} catch (e) {
|
||||||
|
print("Invalid source ${webDTO.source_}");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
super.initState();
|
super.initState();
|
||||||
@ -98,5 +107,5 @@ class _WebView extends State<WebView> {
|
|||||||
viewType: webDTO.source_!,
|
viewType: webDTO.source_!,
|
||||||
) :
|
) :
|
||||||
WebViewWidget(controller: controller!) :
|
WebViewWidget(controller: controller!) :
|
||||||
Center(child: Text("La page internet ne peut pas être affichée, l'url est incorrecte ou vide"));
|
Center(child: Text("La page internet ne peut pas être affichée, l'url est incorrecte ou vide", style: new TextStyle(fontSize: kNoneInfoOrIncorrect)));
|
||||||
} //_webView
|
} //_webView
|
||||||
@ -10,6 +10,7 @@ import 'package:flutter/foundation.dart';
|
|||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
import 'package:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
import 'package:permission_handler/permission_handler.dart';
|
import 'package:permission_handler/permission_handler.dart';
|
||||||
|
import 'package:tablet_app/constants.dart';
|
||||||
|
|
||||||
class DownloadConfigurationWidget extends StatefulWidget {
|
class DownloadConfigurationWidget extends StatefulWidget {
|
||||||
DownloadConfigurationWidget();
|
DownloadConfigurationWidget();
|
||||||
@ -19,27 +20,18 @@ class DownloadConfigurationWidget extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _DownloadConfigurationWidgetState extends State<DownloadConfigurationWidget> {
|
class _DownloadConfigurationWidgetState extends State<DownloadConfigurationWidget> {
|
||||||
int? nbrResources;
|
|
||||||
ValueNotifier<int> currentResourceIndex = ValueNotifier<int>(0);
|
ValueNotifier<int> currentResourceIndex = ValueNotifier<int>(0);
|
||||||
|
ValueNotifier<int> currentResourceNbr = ValueNotifier<int>(-1);
|
||||||
@override
|
bool isAlreadyDownloading = false;
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<bool> download(BuildContext buildContext, TabletAppContext tabletAppContext) async {
|
Future<bool> download(BuildContext buildContext, TabletAppContext tabletAppContext) async {
|
||||||
bool isAllLanguages = true;
|
bool isAllLanguages = true;
|
||||||
|
|
||||||
|
if(!isAlreadyDownloading) {
|
||||||
|
isAlreadyDownloading = true;
|
||||||
|
|
||||||
ExportConfigurationDTO? exportConfigurationDTO;
|
ExportConfigurationDTO? exportConfigurationDTO;
|
||||||
try{
|
try{
|
||||||
print(tabletAppContext.configuration!.id!);
|
|
||||||
print("essai");
|
|
||||||
|
|
||||||
// Retrieve all url from resource to download (get all resource from configuration en somme)
|
// Retrieve all url from resource to download (get all resource from configuration en somme)
|
||||||
exportConfigurationDTO = await tabletAppContext.clientAPI!.configurationApi!.configurationExport(tabletAppContext.configuration!.id!);
|
exportConfigurationDTO = await tabletAppContext.clientAPI!.configurationApi!.configurationExport(tabletAppContext.configuration!.id!);
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
@ -48,86 +40,70 @@ class _DownloadConfigurationWidgetState extends State<DownloadConfigurationWidge
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
print("COUCUO heeere");
|
|
||||||
print(exportConfigurationDTO);
|
|
||||||
print(exportConfigurationDTO.resources!.length);
|
|
||||||
|
|
||||||
exportConfigurationDTO.resources!.forEach((element) {
|
exportConfigurationDTO.resources!.forEach((element) {
|
||||||
print(element.id);
|
print(element.id);
|
||||||
print(element.label);
|
print(element.label);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if(exportConfigurationDTO.resources != null && exportConfigurationDTO.resources!.isNotEmpty) {
|
||||||
if(exportConfigurationDTO != null && exportConfigurationDTO.resources != null && exportConfigurationDTO.resources!.isNotEmpty) {
|
|
||||||
nbrResources = exportConfigurationDTO.resources!.where((resource) => resource.type != ResourceType.ImageUrl && resource.type != ResourceType.VideoUrl && resource.url != null).length;
|
|
||||||
|
|
||||||
print("i'm here");
|
|
||||||
print(nbrResources);
|
|
||||||
Directory? appDocumentsDirectory = await getDownloadsDirectory();
|
|
||||||
String localPath = appDocumentsDirectory!.path;
|
|
||||||
|
|
||||||
print(localPath);
|
|
||||||
|
|
||||||
Map<Permission, PermissionStatus> statuses = await [
|
Map<Permission, PermissionStatus> statuses = await [
|
||||||
Permission.storage,
|
Permission.storage,
|
||||||
].request();
|
].request();
|
||||||
|
|
||||||
print(statuses[Permission.storage]);
|
|
||||||
print(statuses);
|
|
||||||
|
|
||||||
if(statuses[Permission.storage] == PermissionStatus.granted) {
|
if(statuses[Permission.storage] == PermissionStatus.granted) {
|
||||||
|
|
||||||
try{
|
try{
|
||||||
try {
|
try {
|
||||||
Directory directory = Directory('$localPath');
|
Directory directory = Directory('${tabletAppContext.localPath}');
|
||||||
List<FileSystemEntity> allConfigurations = directory.listSync();
|
List<FileSystemEntity> allConfigurations = directory.listSync();
|
||||||
print("LISTING DONE");
|
Directory configurationDirectory = Directory('${tabletAppContext.localPath}/${tabletAppContext.configuration!.id}');
|
||||||
|
|
||||||
Directory configurationDirectory = Directory('$localPath/${tabletAppContext.configuration!.id}');
|
|
||||||
print("configurationDirectory TEST BEFORE");
|
|
||||||
if(!allConfigurations.any((configurationDirectory) => configurationDirectory.uri.pathSegments.any((element) => element == tabletAppContext.configuration!.id))) {
|
if(!allConfigurations.any((configurationDirectory) => configurationDirectory.uri.pathSegments.any((element) => element == tabletAppContext.configuration!.id))) {
|
||||||
// create directory
|
// create directory
|
||||||
print("Trying to create directory");
|
print("Trying to create directory");
|
||||||
configurationDirectory.createSync(recursive: true);
|
configurationDirectory.createSync(recursive: true);
|
||||||
print('Répertoire créé avec succès.');
|
print('Répertoire créé avec succès.');
|
||||||
} else {
|
|
||||||
print('EXISTE D2J0 NIGAUD.');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
print("Listing failed, so try to create directory");
|
print("Listing failed, so try to create directory");
|
||||||
Directory configurationDirectory = Directory('$localPath/${tabletAppContext.configuration!.id}');
|
Directory configurationDirectory = Directory('${tabletAppContext.localPath}/${tabletAppContext.configuration!.id}');
|
||||||
|
|
||||||
configurationDirectory.createSync(recursive: true);
|
configurationDirectory.createSync(recursive: true);
|
||||||
print('Répertoire créé avec succès.');
|
print('Répertoire créé avec succès.');
|
||||||
}
|
}
|
||||||
|
|
||||||
print('Now its time to try listing filesin created directory');
|
Directory configurationDirectory = Directory('${tabletAppContext.localPath}/${tabletAppContext.configuration!.id}');
|
||||||
Directory configurationDirectory = Directory('$localPath/${tabletAppContext.configuration!.id}');
|
|
||||||
List<FileSystemEntity> fileList = configurationDirectory.listSync();
|
List<FileSystemEntity> fileList = configurationDirectory.listSync();
|
||||||
|
|
||||||
print("HERE LIST in directory");
|
|
||||||
|
|
||||||
for (var file in fileList) {
|
for (var file in fileList) {
|
||||||
print(file.uri.pathSegments.last);
|
print(file.uri.pathSegments.last);
|
||||||
}
|
}
|
||||||
|
|
||||||
// foreach ou on va tout télécharger - avec un joli etape 0 / length - on peut rendre tout lent on s'en fou ça ne ce fait qu'une fois
|
var resourcesToDownload = exportConfigurationDTO.resources!.where((resource) => resource.type != ResourceType.ImageUrl && resource.type != ResourceType.VideoUrl && resource.type != ResourceType.JsonUrl && resource.url != null && !fileList.any((fileL) => fileL.uri.pathSegments.last.contains(resource.id!)));
|
||||||
exportConfigurationDTO.resources!.forEach((resource) async {
|
|
||||||
|
|
||||||
if(fileList.any((fileL) => fileL.uri.pathSegments.last.contains(resource.id!))) {
|
currentResourceNbr.value = resourcesToDownload.length;
|
||||||
print("Already exist TRIPLE NIGAUD!");
|
|
||||||
currentResourceIndex.value++;
|
// foreach ou on va tout télécharger - avec un joli etape 0 / length - on peut rendre tout lent on s'en fou ça ne ce fait qu'une fois
|
||||||
} else {
|
for (var resource in resourcesToDownload) {
|
||||||
if(resource.type != ResourceType.ImageUrl && resource.type != ResourceType.VideoUrl && resource.type != ResourceType.JsonUrl && resource.url != null) {
|
bool success = await downloadResource(tabletAppContext, resource, tabletAppContext.localPath!);
|
||||||
bool success = await downloadResource(tabletAppContext, resource, localPath);
|
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
currentResourceIndex.value++;
|
currentResourceIndex.value++;
|
||||||
|
} else {
|
||||||
|
print("NOT SUCCESSS");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Delete others that are no more used
|
||||||
|
var resourceToDelete = fileList.where((fileL) =>
|
||||||
|
!exportConfigurationDTO!.resources!.any((resource) =>
|
||||||
|
resource.id != null && fileL.uri.pathSegments.last.contains(resource.id!)));
|
||||||
|
|
||||||
|
for (var resource in resourceToDelete) {
|
||||||
|
print("resource to DELETE");
|
||||||
|
print(resource.path);
|
||||||
|
// resource.deleteSync();
|
||||||
|
// Preserve call to firebase // TODO uncomment if needed
|
||||||
}
|
}
|
||||||
});
|
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
print("ERRORRRR");
|
print("ERRORRRR");
|
||||||
print(e);
|
print(e);
|
||||||
@ -137,8 +113,8 @@ class _DownloadConfigurationWidgetState extends State<DownloadConfigurationWidge
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Puis après faudra changer tous les appels à une resourceUrl avec un get local de la resource
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,26 +125,53 @@ class _DownloadConfigurationWidgetState extends State<DownloadConfigurationWidge
|
|||||||
Size size = MediaQuery.of(context).size;
|
Size size = MediaQuery.of(context).size;
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
FutureBuilder(future: download(context, tabletAppContext), builder: (context, snapshot) {
|
Spacer(),
|
||||||
if (snapshot.connectionState == ConnectionState.waiting) {
|
|
||||||
// Loader ou indicateur de chargement pendant la vérification
|
|
||||||
return Center(child: CircularProgressIndicator());
|
|
||||||
} else {
|
|
||||||
return Text("Mise à jour finie");
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
ValueListenableBuilder<int>(
|
ValueListenableBuilder<int>(
|
||||||
|
valueListenable: currentResourceNbr,
|
||||||
|
builder: (context, valueNbr, _) {
|
||||||
|
return ValueListenableBuilder<int>(
|
||||||
valueListenable: currentResourceIndex,
|
valueListenable: currentResourceIndex,
|
||||||
builder: (context, value, _) {
|
builder: (context, valueIndex, _) {
|
||||||
return Center(
|
return valueNbr != -1 && valueNbr != 0 ? Center(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.only(bottom: 8.0),
|
||||||
child: Text(
|
child: Text(
|
||||||
value.toString()+'/'+nbrResources.toString(),
|
"${valueIndex.toString()}/${valueNbr.toString()}",
|
||||||
style: TextStyle(fontSize: 15, fontWeight: FontWeight.w500),
|
style: TextStyle(fontSize: 45, fontWeight: FontWeight.w500),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
) : SizedBox(height: 0,width: 0);
|
||||||
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
|
FutureBuilder(future: download(context, tabletAppContext), builder: (context, snapshot) {
|
||||||
|
if (snapshot.connectionState == ConnectionState.waiting) {
|
||||||
|
// Loader ou indicateur de chargement pendant la vérification
|
||||||
|
Color primaryColor = tabletAppContext.configuration!.primaryColor != null ? new Color(int.parse(tabletAppContext.configuration!.primaryColor!.split('(0x')[1].split(')')[0], radix: 16)) : kTestSecondColor;
|
||||||
|
return Center(child: CircularProgressIndicator(color: primaryColor));
|
||||||
|
} else {
|
||||||
|
return ValueListenableBuilder<int>(
|
||||||
|
valueListenable: currentResourceNbr,
|
||||||
|
builder: (context, valueNbr, _) {
|
||||||
|
return ValueListenableBuilder<int>(
|
||||||
|
valueListenable: currentResourceIndex,
|
||||||
|
builder: (context, valueIndex, _) {
|
||||||
|
return Center(
|
||||||
|
child: Text(
|
||||||
|
valueIndex == valueNbr && valueNbr != -1 ? valueNbr == 0 ? "Tout est à jour" : "Mise à jour finie" : "Mise à jour en cours",
|
||||||
|
style: TextStyle(fontSize: 25),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
Spacer()
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user