mirror of
https://bitbucket.org/FransoletThomas/tablet-app.git
synced 2025-12-06 08:31:19 +00:00
wip customCachedResources
This commit is contained in:
parent
7a5342dc24
commit
29e4863493
@ -1,5 +1,8 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="be.musee.de.la.fraise.tablet_app">
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||
<application
|
||||
android:label="MyMuseum"
|
||||
android:usesCleartextTraffic="true"
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
@ -9,8 +10,9 @@ 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);
|
||||
const AudioPlayerFloatingContainer({Key? key, required this.file, required this.audioBytes, required this.resourceURl, required this.isAuto}) : super(key: key);
|
||||
|
||||
final File? file;
|
||||
final Uint8List? audioBytes;
|
||||
final String resourceURl;
|
||||
final bool isAuto;
|
||||
@ -21,7 +23,7 @@ class AudioPlayerFloatingContainer extends StatefulWidget {
|
||||
|
||||
class _AudioPlayerFloatingContainerState extends State<AudioPlayerFloatingContainer> {
|
||||
AudioPlayer player = AudioPlayer();
|
||||
late Uint8List audiobytes;
|
||||
Uint8List? audiobytes = null;
|
||||
bool isplaying = false;
|
||||
bool audioplayed = false;
|
||||
int currentpos = 0;
|
||||
@ -37,6 +39,10 @@ class _AudioPlayerFloatingContainerState extends State<AudioPlayerFloatingContai
|
||||
audiobytes = widget.audioBytes!;
|
||||
}
|
||||
|
||||
if(widget.file != null) {
|
||||
audiobytes = await fileToUint8List(widget.file!);
|
||||
}
|
||||
|
||||
player.durationStream.listen((Duration? d) { //get the duration of audio
|
||||
if(d != null) {
|
||||
maxduration = d.inSeconds;
|
||||
@ -101,10 +107,17 @@ class _AudioPlayerFloatingContainerState extends State<AudioPlayerFloatingContai
|
||||
});
|
||||
});*/
|
||||
|
||||
await player.dynamicSet(url: widget.resourceURl);
|
||||
if(audiobytes != null) {
|
||||
print("GOT AUDIOBYYYTES - LOCALLY SOSO");
|
||||
await player.setAudioSource(LoadedSource(audiobytes!));
|
||||
} else {
|
||||
print("GET SOUND BY URL");
|
||||
await player.dynamicSet(url: widget.resourceURl);
|
||||
}
|
||||
|
||||
if(widget.isAuto) {
|
||||
//player.play(BytesSource(audiobytes));
|
||||
//await player.setAudioSource(LoadedSource(audiobytes));
|
||||
//
|
||||
player.play();
|
||||
setState(() {
|
||||
isplaying = true;
|
||||
@ -122,6 +135,11 @@ class _AudioPlayerFloatingContainerState extends State<AudioPlayerFloatingContai
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
Future<Uint8List> fileToUint8List(File file) async {
|
||||
List<int> bytes = await file.readAsBytes();
|
||||
return Uint8List.fromList(bytes);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final appContext = Provider.of<AppContext>(context);
|
||||
|
||||
122
lib/Components/cached_custom_resource.dart
Normal file
122
lib/Components/cached_custom_resource.dart
Normal file
@ -0,0 +1,122 @@
|
||||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:manager_api/api.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:provider/provider.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';
|
||||
|
||||
class CachedCustomResource extends StatelessWidget {
|
||||
final ResourceDTO resourceDTO;
|
||||
final bool isAuto;
|
||||
final bool webView;
|
||||
final BoxFit fit;
|
||||
|
||||
CachedCustomResource({
|
||||
required this.resourceDTO,
|
||||
required this.isAuto,
|
||||
required this.webView,
|
||||
this.fit = BoxFit.cover,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final appContext = Provider.of<AppContext>(context);
|
||||
TabletAppContext tabletAppContext = appContext.getContext();
|
||||
Size size = MediaQuery.of(context).size;
|
||||
|
||||
Color primaryColor = new Color(int.parse(tabletAppContext.configuration!.primaryColor!.split('(0x')[1].split(')')[0], radix: 16));
|
||||
|
||||
if(resourceDTO.type == ResourceType.ImageUrl || resourceDTO.type == ResourceType.VideoUrl)
|
||||
{
|
||||
// Image Url or Video Url don't care, just get resource
|
||||
if(resourceDTO.type == ResourceType.ImageUrl) {
|
||||
return CachedNetworkImage(
|
||||
imageUrl: resourceDTO.url!,
|
||||
fit: BoxFit.fill,
|
||||
progressIndicatorBuilder: (context, url, downloadProgress) =>
|
||||
CircularProgressIndicator(value: downloadProgress.progress, color: primaryColor),
|
||||
errorWidget: (context, url, error) => Icon(Icons.error),
|
||||
);
|
||||
} else {
|
||||
if(resourceDTO.url == null) {
|
||||
return Center(child: Text("Error loading video"));
|
||||
} else {
|
||||
return VideoViewerYoutube(videoUrl: resourceDTO.url!, isAuto: isAuto, webView: webView);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Check if exist on local storage, if no, just show it via url
|
||||
print("Check local storage in cached custom resource");
|
||||
return FutureBuilder<File?>(
|
||||
future: _checkIfLocalResourceExists(tabletAppContext),
|
||||
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
|
||||
|
||||
switch(resourceDTO.type) {
|
||||
case ResourceType.Image :
|
||||
return CachedNetworkImage(
|
||||
imageUrl: resourceDTO.url!,
|
||||
fit: fit,
|
||||
placeholder: (context, url) => CircularProgressIndicator(),
|
||||
errorWidget: (context, url, error) => Icon(Icons.error),
|
||||
);
|
||||
case ResourceType.Video :
|
||||
return VideoViewer(file: null, videoUrl: resourceDTO.url!);
|
||||
case ResourceType.Audio :
|
||||
return AudioPlayerFloatingContainer(file: null, audioBytes: null, resourceURl: resourceDTO.url!, isAuto: isAuto);
|
||||
default:
|
||||
return Text("Not supported type");
|
||||
}
|
||||
} else {
|
||||
|
||||
switch(resourceDTO.type) {
|
||||
case ResourceType.Image :
|
||||
return Image.file(
|
||||
snapshot.data!,
|
||||
fit: fit,
|
||||
);
|
||||
case ResourceType.Video :
|
||||
return VideoViewer(file: snapshot.data!, videoUrl: resourceDTO.url!);
|
||||
case ResourceType.Audio :
|
||||
return AudioPlayerFloatingContainer(file: snapshot.data!, audioBytes: null, resourceURl: resourceDTO.url!, isAuto: isAuto);
|
||||
default:
|
||||
return Text("Not supported type");
|
||||
}
|
||||
// Utilisation de l'image locale
|
||||
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<File?> _checkIfLocalResourceExists(TabletAppContext tabletAppContext) async {
|
||||
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(resourceDTO.id!))) {
|
||||
File file = File(fileList.firstWhere((fileL) => fileL.uri.pathSegments.last.contains(resourceDTO.id!)).path);
|
||||
return file;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
Future<String> get localPath async {
|
||||
Directory? appDocumentsDirectory = await getDownloadsDirectory();
|
||||
return appDocumentsDirectory!.path;
|
||||
}
|
||||
}
|
||||
@ -11,10 +11,14 @@ import 'package:tablet_app/Components/video_viewer_youtube.dart';
|
||||
import 'package:tablet_app/Models/tabletContext.dart';
|
||||
import 'package:tablet_app/app_context.dart';
|
||||
|
||||
import 'cached_custom_resource.dart';
|
||||
|
||||
showElementForResource(ResourceDTO resourceDTO, AppContext appContext, bool isAuto, bool webView) {
|
||||
TabletAppContext tabletAppContext = appContext.getContext();
|
||||
Color primaryColor = new Color(int.parse(tabletAppContext.configuration!.primaryColor!.split('(0x')[1].split(')')[0], radix: 16));
|
||||
|
||||
return CachedCustomResource(resourceDTO: resourceDTO, isAuto: isAuto, webView: webView);
|
||||
|
||||
switch(resourceDTO.type) {
|
||||
case ResourceType.Image:
|
||||
case ResourceType.ImageUrl:
|
||||
@ -45,7 +49,7 @@ showElementForResource(ResourceDTO resourceDTO, AppContext appContext, bool isAu
|
||||
},
|
||||
);*/
|
||||
case ResourceType.Audio:
|
||||
return AudioPlayerFloatingContainer(audioBytes: null, resourceURl: resourceDTO.url!, isAuto: isAuto);
|
||||
return AudioPlayerFloatingContainer(file: null, audioBytes: null, resourceURl: resourceDTO.url!, isAuto: isAuto);
|
||||
/*return FutureBuilder(
|
||||
future: getAudio(resourceDTO.url, appContext),
|
||||
builder: (context, AsyncSnapshot<dynamic> snapshot) {
|
||||
@ -76,7 +80,7 @@ showElementForResource(ResourceDTO resourceDTO, AppContext appContext, bool isAu
|
||||
if(resourceDTO.url == null) {
|
||||
return Center(child: Text("Error loading video"));
|
||||
} else {
|
||||
return VideoViewer(videoUrl: resourceDTO.url!);
|
||||
return VideoViewer(file: null, videoUrl: resourceDTO.url!);
|
||||
}
|
||||
case ResourceType.VideoUrl:
|
||||
if(resourceDTO.url == null) {
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:cached_video_player/cached_video_player.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:tablet_app/Components/loading_common.dart';
|
||||
@ -6,7 +8,8 @@ import '../../constants.dart';
|
||||
|
||||
class VideoViewer extends StatefulWidget {
|
||||
final String videoUrl;
|
||||
VideoViewer({required this.videoUrl});
|
||||
final File? file;
|
||||
VideoViewer({required this.videoUrl, required this.file});
|
||||
|
||||
@override
|
||||
_VideoViewer createState() => _VideoViewer();
|
||||
@ -18,11 +21,19 @@ class _VideoViewer extends State<VideoViewer> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_controller = CachedVideoPlayerController.network(widget.videoUrl) // Uri.parse()
|
||||
..initialize().then((_) {
|
||||
// Ensure the first frame is shown after the video is initialized, even before the play button has been pressed.
|
||||
setState(() {});
|
||||
});
|
||||
if(widget.file != null) {
|
||||
_controller = CachedVideoPlayerController.file(widget.file!) // Uri.parse()
|
||||
..initialize().then((_) {
|
||||
// Ensure the first frame is shown after the video is initialized, even before the play button has been pressed.
|
||||
setState(() {});
|
||||
});
|
||||
} else {
|
||||
_controller = CachedVideoPlayerController.network(widget.videoUrl) // Uri.parse()
|
||||
..initialize().then((_) {
|
||||
// Ensure the first frame is shown after the video is initialized, even before the play button has been pressed.
|
||||
setState(() {});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@ -17,6 +17,7 @@ class TabletAppContext with ChangeNotifier{
|
||||
String? deviceId;
|
||||
String? instanceId;
|
||||
Size? puzzleSize;
|
||||
String? localPath;
|
||||
|
||||
TabletAppContext({this.id, this.deviceId, this.host, this.configuration, this.language, this.instanceId, this.clientAPI});
|
||||
|
||||
|
||||
@ -26,6 +26,7 @@ import 'package:tablet_app/Screens/Puzzle/puzzle_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/Web/web_view.dart';
|
||||
import 'package:tablet_app/Services/downloadService.dart';
|
||||
import 'package:tablet_app/app_context.dart';
|
||||
import 'package:tablet_app/constants.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
@ -418,7 +419,32 @@ class _MainViewWidget extends State<MainViewWidget> {
|
||||
),
|
||||
),
|
||||
]),
|
||||
)
|
||||
),
|
||||
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,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:carousel_slider/carousel_slider.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
@ -6,9 +7,11 @@ import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_widget_from_html/flutter_widget_from_html.dart';
|
||||
import 'package:manager_api/api.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:tablet_app/Components/show_element_for_resource.dart';
|
||||
import 'package:tablet_app/Components/video_viewer.dart';
|
||||
import 'package:tablet_app/Models/tabletContext.dart';
|
||||
import 'package:tablet_app/app_context.dart';
|
||||
import 'package:tablet_app/constants.dart';
|
||||
import 'package:photo_view/photo_view.dart';
|
||||
@ -251,6 +254,29 @@ class _SliderView extends State<SliderView> {
|
||||
|
||||
switch(i.resourceType) {
|
||||
case ResourceType.Image:
|
||||
TabletAppContext tabletAppContext = appContext.getContext();
|
||||
Directory configurationDirectory = Directory('${tabletAppContext.localPath}/${tabletAppContext.configuration!.id}');
|
||||
List<FileSystemEntity> fileList = configurationDirectory.listSync();
|
||||
|
||||
var imageProvider = null;
|
||||
if(fileList.any((fileL) => fileL.uri.pathSegments.last.contains(i.resourceId!))) {
|
||||
File file = File(fileList.firstWhere((fileL) => fileL.uri.pathSegments.last.contains(i.resourceId!)).path);
|
||||
imageProvider = FileImage(file);
|
||||
} else {
|
||||
imageProvider = new CachedNetworkImageProvider(i.resourceUrl!,);
|
||||
}
|
||||
|
||||
widgetToInclude = PhotoView(
|
||||
imageProvider: imageProvider,
|
||||
minScale: PhotoViewComputedScale.contained * 0.8,
|
||||
maxScale: PhotoViewComputedScale.contained * 3.0,
|
||||
backgroundDecoration: BoxDecoration(
|
||||
color: kBackgroundSecondGrey,
|
||||
shape: BoxShape.rectangle,
|
||||
borderRadius: BorderRadius.circular(15.0),
|
||||
),
|
||||
);
|
||||
break;
|
||||
case ResourceType.ImageUrl:
|
||||
widgetToInclude = PhotoView(
|
||||
imageProvider: CachedNetworkImageProvider(i.resourceUrl!),/*new NetworkImage(
|
||||
|
||||
219
lib/Services/downloadService.dart
Normal file
219
lib/Services/downloadService.dart
Normal file
@ -0,0 +1,219 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:manager_api/api.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:tablet_app/Models/tabletContext.dart';
|
||||
import 'package:tablet_app/app_context.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:permission_handler/permission_handler.dart';
|
||||
|
||||
class DownloadConfigurationWidget extends StatefulWidget {
|
||||
DownloadConfigurationWidget();
|
||||
|
||||
@override
|
||||
State<DownloadConfigurationWidget> createState() => _DownloadConfigurationWidgetState();
|
||||
}
|
||||
|
||||
class _DownloadConfigurationWidgetState extends State<DownloadConfigurationWidget> {
|
||||
int? nbrResources;
|
||||
ValueNotifier<int> currentResourceIndex = ValueNotifier<int>(0);
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
Future<bool> download(BuildContext buildContext, TabletAppContext tabletAppContext) async {
|
||||
bool isAllLanguages = true;
|
||||
|
||||
ExportConfigurationDTO? exportConfigurationDTO;
|
||||
try{
|
||||
print(tabletAppContext.configuration!.id!);
|
||||
print("essai");
|
||||
|
||||
// Retrieve all url from resource to download (get all resource from configuration en somme)
|
||||
exportConfigurationDTO = await tabletAppContext.clientAPI!.configurationApi!.configurationExport(tabletAppContext.configuration!.id!);
|
||||
} catch(e) {
|
||||
print("Erreur lors du téléchargement de la configuration et de ses ressources !");
|
||||
print(e);
|
||||
return false;
|
||||
}
|
||||
|
||||
print("COUCUO heeere");
|
||||
print(exportConfigurationDTO);
|
||||
print(exportConfigurationDTO.resources!.length);
|
||||
|
||||
exportConfigurationDTO.resources!.forEach((element) {
|
||||
print(element.id);
|
||||
print(element.label);
|
||||
});
|
||||
|
||||
|
||||
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 [
|
||||
Permission.storage,
|
||||
].request();
|
||||
|
||||
print(statuses[Permission.storage]);
|
||||
print(statuses);
|
||||
|
||||
if(statuses[Permission.storage] == PermissionStatus.granted) {
|
||||
|
||||
try{
|
||||
Directory directory = Directory('$localPath');
|
||||
List<FileSystemEntity> allConfigurations = directory.listSync();
|
||||
|
||||
for (var file in allConfigurations) {
|
||||
print('file.uri.pathSegments');
|
||||
print(file.uri.pathSegments);
|
||||
print('file.uri.pathSegments.last');
|
||||
print(file.uri.pathSegments.last);
|
||||
}
|
||||
|
||||
Directory configurationDirectory = Directory('$localPath/${tabletAppContext.configuration!.id}');
|
||||
|
||||
if(!allConfigurations.any((configurationDirectory) => configurationDirectory.uri.pathSegments.any((element) => element == tabletAppContext.configuration!.id))) {
|
||||
// create directory
|
||||
configurationDirectory.createSync(recursive: true);
|
||||
print('Répertoire créé avec succès.');
|
||||
} else {
|
||||
print('EXISTE D2J0 NIGAUD.');
|
||||
}
|
||||
|
||||
List<FileSystemEntity> fileList = configurationDirectory.listSync();
|
||||
|
||||
print("HERE LIST in directory");
|
||||
|
||||
for (var file in fileList) {
|
||||
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
|
||||
exportConfigurationDTO.resources!.forEach((resource) async {
|
||||
|
||||
if(fileList.any((fileL) => fileL.uri.pathSegments.last.contains(resource.id!))) {
|
||||
print("Already exist TRIPLE NIGAUD!");
|
||||
currentResourceIndex.value++;
|
||||
} else {
|
||||
if(resource.type != ResourceType.ImageUrl && resource.type != ResourceType.VideoUrl && resource.url != null) {
|
||||
bool success = await downloadResource(tabletAppContext, resource, localPath);
|
||||
|
||||
if (success) {
|
||||
currentResourceIndex.value++;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch(e) {
|
||||
print("ERRORRRR");
|
||||
print(e);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Puis après faudra changer tous les appels à une resourceUrl avec un get local de la resource
|
||||
return true;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final appContext = Provider.of<AppContext>(context);
|
||||
TabletAppContext tabletAppContext = appContext.getContext();
|
||||
Size size = MediaQuery.of(context).size;
|
||||
|
||||
return Column(
|
||||
children: [
|
||||
FutureBuilder(future: download(context, tabletAppContext), builder: (context, snapshot) {
|
||||
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>(
|
||||
valueListenable: currentResourceIndex,
|
||||
builder: (context, value, _) {
|
||||
return Center(
|
||||
child: Text(
|
||||
value.toString()+'/'+nbrResources.toString(),
|
||||
style: TextStyle(fontSize: 15, fontWeight: FontWeight.w500),
|
||||
),
|
||||
);
|
||||
}
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> downloadResource(TabletAppContext tabletAppContext, ResourceDTO resourceDTO, String localPath) async {
|
||||
try {
|
||||
// Téléchargement de la ressource depuis l'URL
|
||||
http.Response response = await http.get(Uri.parse(resourceDTO.url!));
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
// Vérification de l'en-tête Content-Type
|
||||
String contentType = response.headers["content-type"] ?? "";
|
||||
|
||||
// Déduction de l'extension en fonction du Content-Type
|
||||
String extension = _getExtensionFromContentType(contentType);
|
||||
|
||||
print("LOCAL PATTH");
|
||||
print(localPath);
|
||||
|
||||
File file = File('$localPath/${tabletAppContext.configuration!.id}/${resourceDTO.id}.$extension');
|
||||
|
||||
// Écriture du contenu téléchargé dans le fichier local
|
||||
await file.writeAsBytes(response.bodyBytes);
|
||||
|
||||
return true;
|
||||
} else {
|
||||
print("Échec du téléchargement de la ressource - ${response.statusCode}");
|
||||
return false;
|
||||
}
|
||||
} catch (e) {
|
||||
print("Erreur lors du téléchargement de la ressource !");
|
||||
print(e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
String _getExtensionFromContentType(String contentType) {
|
||||
Map<String, String> contentTypeToExtension = {
|
||||
"image/jpeg": "jpg",
|
||||
"image/jpg": "jpg",
|
||||
"image/png": "png",
|
||||
"image/gif": "gif",
|
||||
"audio/mp3": "mp3",
|
||||
"video/mp4": "mp4",
|
||||
"video/webm": "webm",
|
||||
"video/avi": "avi",
|
||||
"video/quicktime": "mov",
|
||||
"application/pdf": "pdf",
|
||||
"application/json": "json"
|
||||
};
|
||||
|
||||
return contentTypeToExtension[contentType] ?? "unknown";
|
||||
}
|
||||
@ -4,6 +4,7 @@ import 'package:firebase_core/firebase_core.dart';
|
||||
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:provider/provider.dart';
|
||||
import 'package:tablet_app/client.dart';
|
||||
import 'Helpers/DatabaseHelper.dart';
|
||||
@ -24,6 +25,9 @@ void main() async {
|
||||
localContext = await DatabaseHelper.instance.getData();
|
||||
}
|
||||
|
||||
Directory? appDocumentsDirectory = await getDownloadsDirectory();
|
||||
String localPath = appDocumentsDirectory!.path;
|
||||
|
||||
if(localContext != null && localContext.host != null) {
|
||||
print("we've got an local db !");
|
||||
print(localContext);
|
||||
@ -38,6 +42,8 @@ void main() async {
|
||||
DeviceDetailDTO? device = await localContext.clientAPI!.deviceApi!.deviceGetDetail(localContext.deviceId!);
|
||||
localContext.configuration!.id = device!.configurationId;
|
||||
localContext.instanceId = device.instanceId;
|
||||
localContext.localPath = localPath;
|
||||
|
||||
if (device.configurationId == null) {
|
||||
print("device.configurationId == null");
|
||||
localContext.configuration = null;
|
||||
@ -46,6 +52,8 @@ void main() async {
|
||||
} else {
|
||||
print("NO LOCAL DB !");
|
||||
localContext = TabletAppContext(host: "https://api.myinfomate.be");
|
||||
|
||||
localContext.localPath = localPath;
|
||||
}
|
||||
|
||||
if(kIsWeb) {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// This is a generated file; do not edit or check into version control.
|
||||
FLUTTER_ROOT=/Users/thomasfransolet/Documents/flutter
|
||||
FLUTTER_APPLICATION_PATH=/Users/thomasfransolet/Documents/Proj/MyMuseum/tablet_app
|
||||
FLUTTER_ROOT=C:\PROJ\flutter
|
||||
FLUTTER_APPLICATION_PATH=C:\Users\ThomasFransolet\Documents\Documents\Perso\MuseeDeLaFraise\tablet-app
|
||||
COCOAPODS_PARALLEL_CODE_SIGN=true
|
||||
FLUTTER_BUILD_DIR=build
|
||||
FLUTTER_BUILD_NAME=2.0.0
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
# This is a generated file; do not edit or check into version control.
|
||||
export "FLUTTER_ROOT=/Users/thomasfransolet/Documents/flutter"
|
||||
export "FLUTTER_APPLICATION_PATH=/Users/thomasfransolet/Documents/Proj/MyMuseum/tablet_app"
|
||||
export "FLUTTER_ROOT=C:\PROJ\flutter"
|
||||
export "FLUTTER_APPLICATION_PATH=C:\Users\ThomasFransolet\Documents\Documents\Perso\MuseeDeLaFraise\tablet-app"
|
||||
export "COCOAPODS_PARALLEL_CODE_SIGN=true"
|
||||
export "FLUTTER_BUILD_DIR=build"
|
||||
export "FLUTTER_BUILD_NAME=2.0.0"
|
||||
|
||||
@ -152,8 +152,8 @@ class ConfigurationApi {
|
||||
/// * [String] id (required):
|
||||
///
|
||||
/// * [String] language:
|
||||
Future<MultipartFile?> configurationExport(String id, { String? language, }) async {
|
||||
final response = await configurationExportWithHttpInfo(id, language: language, );
|
||||
Future<ExportConfigurationDTO> configurationExport(String id,) async {
|
||||
final response = await configurationExportWithHttpInfo(id,);
|
||||
if (response.statusCode >= HttpStatus.badRequest) {
|
||||
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
||||
}
|
||||
@ -161,10 +161,10 @@ class ConfigurationApi {
|
||||
// At the time of writing this, `dart:convert` will throw an "Unexpected end of input"
|
||||
// FormatException when trying to decode an empty string.
|
||||
if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) {
|
||||
return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'MultipartFile',) as MultipartFile;
|
||||
|
||||
return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'ExportConfigurationDTO',) as ExportConfigurationDTO;
|
||||
|
||||
}
|
||||
return null;
|
||||
return Future<ExportConfigurationDTO>.value(null);
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'GET /api/Configuration' operation and returns the [Response].
|
||||
|
||||
@ -36,7 +36,7 @@ dependencies:
|
||||
|
||||
flare_flutter: ^3.0.2
|
||||
provider: ^6.0.5
|
||||
http: ^1.1.0
|
||||
http: ^1.2.0
|
||||
auto_size_text: ^3.0.0
|
||||
fluttertoast:
|
||||
device_info: ^2.0.2 # DISCONTINUED
|
||||
@ -55,6 +55,8 @@ dependencies:
|
||||
cached_video_player: ^2.0.4
|
||||
cached_network_image: ^3.3.1
|
||||
just_audio_cache: ^0.1.2
|
||||
path_provider: ^2.1.2
|
||||
permission_handler: ^11.2.0
|
||||
|
||||
openapi_generator_cli: ^4.13.1
|
||||
openapi_generator: ^4.13.1
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
|
||||
#include <firebase_core/firebase_core_plugin_c_api.h>
|
||||
#include <firebase_storage/firebase_storage_plugin_c_api.h>
|
||||
#include <permission_handler_windows/permission_handler_windows_plugin.h>
|
||||
#include <url_launcher_windows/url_launcher_windows.h>
|
||||
|
||||
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||
@ -15,6 +16,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||
registry->GetRegistrarForPlugin("FirebaseCorePluginCApi"));
|
||||
FirebaseStoragePluginCApiRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("FirebaseStoragePluginCApi"));
|
||||
PermissionHandlerWindowsPluginRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin"));
|
||||
UrlLauncherWindowsRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("UrlLauncherWindows"));
|
||||
}
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
list(APPEND FLUTTER_PLUGIN_LIST
|
||||
firebase_core
|
||||
firebase_storage
|
||||
permission_handler_windows
|
||||
url_launcher_windows
|
||||
)
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user