Download all languages if admin + show it in admin pop up + add isAllLanguages

This commit is contained in:
Fransolet Thomas 2023-04-06 21:56:06 +02:00
parent 59a16cde74
commit d38cdffe5a
11 changed files with 241 additions and 46 deletions

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:mymuseum_visitapp/Components/check_input_container.dart';
import 'package:mymuseum_visitapp/Helpers/DatabaseHelper.dart';
import 'package:mymuseum_visitapp/Helpers/translationHelper.dart';
import 'package:mymuseum_visitapp/Models/visitContext.dart';
@ -31,13 +32,64 @@ class _AdminPopupState extends State<AdminPopup> {
isPasswordOk = visitAppContext!.isAdmin!;
return Container(
width: size.width*0.65,
height: isPasswordOk ? size.height*0.1 : size.height*0.25,
width: size.width*0.7,
height: isPasswordOk ? size.height*0.45 : size.height*0.15,
margin: const EdgeInsets.all(kDefaultPadding),
child: isPasswordOk ? Column(
children: [
Text("Audios qui ne fonctionnent pas :"),
Text("TODO list"),
SizedBox(
height: size.height*0.06,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: CheckInputContainer(label: "Mode admin", isChecked: visitAppContext!.isAdmin, onChanged: (value) {
visitAppContext!.isAdmin = value;
appContext.setContext(visitAppContext!);
DatabaseHelper.instance.updateTableMain(DatabaseTableType.main, visitAppContext!);
}),
),
),
SizedBox(
height: size.height*0.06,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: CheckInputContainer(label: "Télécharger langues", isChecked: visitAppContext!.isAllLanguages, onChanged: (value) {
visitAppContext!.isAllLanguages = value;
appContext.setContext(visitAppContext!);
DatabaseHelper.instance.updateTableMain(DatabaseTableType.main, visitAppContext!);
}),
),
),
const Text("Audios qui ne fonctionnent pas :"),
const SizedBox(
height: 15,
),
Container(
decoration: BoxDecoration(
shape: BoxShape.rectangle,
border: Border.all(width: 1.5, color: kSecondGrey),
borderRadius: BorderRadius.circular(10.0),
),
height: size.height*0.25,
width: size.width*0.7,
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
if(visitAppContext!.audiosNotWorking.isEmpty)
const Padding(
padding: EdgeInsets.all(8.0),
child: Text("Rien mais téléchargez la visite pour être sûr"),
),
if(visitAppContext!.audiosNotWorking.isNotEmpty)
for(var audio in visitAppContext!.audiosNotWorking)
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(audio.label!.isNotEmpty ? audio.label! : audio.id!),
)
],
)
),
)
],
) :
Column(
@ -47,7 +99,7 @@ class _AdminPopupState extends State<AdminPopup> {
Text("Mot de passe admin"),
SizedBox(
width: size.width*0.65,
height: size.height *0.2,
height: size.height *0.1,
child: TextFormField(
controller: _controller,
onChanged: (value) {

View File

@ -32,9 +32,9 @@ class _LanguageSelection extends State<LanguageSelection> with TickerProviderSta
//print(configurationLanguages);
languagesEnable = configurationLanguages ?? languages;
selectedLanguage = visitAppContext.language;
var isAdmin = visitAppContext.isAdmin ?? false;
var isAllLanguages = visitAppContext.isAllLanguages ?? false;
if((visitAppContext.configuration != null && visitAppContext.configuration!.isOffline! && !isAdmin) || widget.configurationDTO != null)
if((visitAppContext.configuration != null && visitAppContext.configuration!.isOffline! && !isAllLanguages) || widget.configurationDTO != null)
{
if(widget.configurationDTO != null) {
languagesEnable = widget.configurationDTO!.languages ?? languages;

View File

@ -0,0 +1,88 @@
import 'package:auto_size_text/auto_size_text.dart';
import 'package:flutter/material.dart';
import '../constants.dart';
class CheckInputContainer extends StatefulWidget {
final bool? isChecked;
final IconData? icon;
final String label;
final ValueChanged<bool> onChanged;
final double fontSize;
const CheckInputContainer({
Key? key,
this.isChecked,
this.icon,
required this.label,
required this.onChanged,
this.fontSize = 20
}) : super(key: key);
@override
_CheckInputContainerState createState() => _CheckInputContainerState();
}
class _CheckInputContainerState extends State<CheckInputContainer> {
bool? isChecked;
@override
void initState() {
setState(() {
isChecked = widget.isChecked;
});
super.initState();
}
@override
Widget build(BuildContext context) {
return Container(
child: Row(
children: [
Align(
alignment: AlignmentDirectional.centerStart,
child: Row(
children: [
if(widget.icon != null)
Padding(
padding: const EdgeInsets.only(right: 8.0),
child: Icon(
widget.icon,
color: kMainColor,
size: 25.0,
),
),
if(widget.label != null)
AutoSizeText(
widget.label,
style: new TextStyle(fontSize: widget.fontSize, fontWeight: FontWeight.w300),
maxLines: 2,
maxFontSize: widget.fontSize,
textAlign: TextAlign.center,
),
],
)
),
Padding(
padding: const EdgeInsets.all(10.0),
child: Container(
width: 50,
height: 50,
child: Checkbox(
shape: CircleBorder(),
value: isChecked,
checkColor: Colors.white,
activeColor: kMainColor,
onChanged: (bool? value) {
setState(() {
isChecked = value;
});
widget.onChanged(value!);
},
),
),
),
],
),
);
}
}

View File

@ -63,6 +63,7 @@ class DatabaseHelper {
static const columnSectionType = 'sectionType';
static const columnIsAdmin = 'isAdmin';
static const columnIsAllLanguages = 'isAllLanguages';
DatabaseHelper._privateConstructor();
@ -155,7 +156,8 @@ class DatabaseHelper {
$columnId TEXT NOT NULL PRIMARY KEY,
$columnLanguage TEXT NOT NULL,
$columnInstanceId TEXT NOT NULL,
$columnIsAdmin BOOLEAN NOT NULL CHECK ($columnIsAdmin IN (0,1))
$columnIsAdmin BOOLEAN NOT NULL CHECK ($columnIsAdmin IN (0,1)),
$columnIsAllLanguages BOOLEAN CHECK ($columnIsAllLanguages IN (0,1))
)
''');
break;
@ -241,9 +243,16 @@ class DatabaseHelper {
var test = await db.rawQuery(checkQuery);
if(test.where((e) => e.toString().contains(columnIsAdmin)).isEmpty) {
print("update .. columnIsAdmin");
await db.rawQuery("ALTER TABLE $nameOfTable Add $columnIsAdmin BOOLEAN CHECK ($columnIsAdmin IN (0,1))");
} else {
print("IN");
print("IN columnIsAdmin");
}
if(test.where((e) => e.toString().contains(columnIsAllLanguages)).isEmpty) {
print("update .. columnIsAllLanguages");
await db.rawQuery("ALTER TABLE $nameOfTable Add $columnIsAllLanguages BOOLEAN CHECK ($columnIsAllLanguages IN (0,1))");
} else {
print("IN columnIsAllLanguages");
}
DatabaseHelper.instance.insert(DatabaseTableType.main, visitAppContext.toMap());
} catch (e) {
@ -310,6 +319,7 @@ class DatabaseHelper {
instanceId: element["instanceId"],
language: element["language"],
isAdmin: element["isAdmin"] == 1 ? true : false,
isAllLanguages: element["isAllLanguages"] == 1 ? true : false,
);
break;
case DatabaseTableType.configurations:

View File

@ -5,6 +5,7 @@ class ResourceModel {
String? id = "";
String? data = "";
String? source = "";
String? label = "";
ResourceType? type;
ResourceModel({this.id, this.data, this.source, this.type});
@ -29,6 +30,6 @@ class ResourceModel {
@override
String toString() {
return 'ResourceModel{id: $id, type: $type, source: $source, data: $data}';
return 'ResourceModel{id: $id, type: $type, source: $source, data: $data, label: $label}';
}
}

View File

@ -22,15 +22,17 @@ class VisitAppContext with ChangeNotifier{
List<ResourceModel> audiosNotWorking = [];
bool? isAdmin = false;
bool? isAllLanguages = false;
VisitAppContext({this.language, this.id, this.configuration, this.isAdmin, this.instanceId});
VisitAppContext({this.language, this.id, this.configuration, this.isAdmin, this.isAllLanguages, this.instanceId});
Map<String, dynamic> toMap() {
return {
'id': id,
'instanceId': instanceId,
'language': language,
'isAdmin': isAdmin
'isAdmin': isAdmin != null ? isAdmin! ? 1 : 0 : 0,
'isAllLanguages': isAllLanguages != null ? isAllLanguages! ? 1 : 0 : 0
};
}

View File

@ -45,7 +45,7 @@ class _AudioPlayerFloatingContainerState extends State<AudioPlayerFloatingContai
//player.bufferedPositionStream
player.positionStream.listen((event) {
if(event != null) {
if(event != null && durationAudio != null) {
currentpos = event.inMilliseconds; //get the current position of playing audio

View File

@ -224,8 +224,7 @@ class _ConfigurationsListState extends State<ConfigurationsList> {
margin: const EdgeInsets.all(8),
child: InkWell(
onTap: () async {
await downloadClicked(
appContext, configurations[index]);
await downloadClicked(context, appContext, configurations[index]);
widget.requestRefresh();
},
child: configurations[index].isOffline! &&
@ -245,8 +244,7 @@ class _ConfigurationsListState extends State<ConfigurationsList> {
itemCount: configurations.length);
}
Future<void> downloadClicked(
AppContext appContext, ConfigurationDTO configuration) async {
Future<void> downloadClicked(BuildContext buildContext, AppContext appContext, ConfigurationDTO configuration) async {
bool isCancel = false;
//if(!alreadyDownloaded.any((c) => c == configuration.id)) {
await showDialog(
@ -340,12 +338,17 @@ class _ConfigurationsListState extends State<ConfigurationsList> {
);
});
var isFinish =
await DownloadConfiguration.download(appContext, configuration);
print("C'EST FINI.");
print(isFinish);
var audiosNotWorking = await DownloadConfiguration.download(buildContext, appContext, configuration);
print("C'EST FINI. - nombre d'audios qui ne fonctionnent pas");
print(audiosNotWorking.length);
Navigator.of(context).pop();
VisitAppContext visitAppContext = appContext.getContext() as VisitAppContext;
visitAppContext.audiosNotWorking = [];
visitAppContext.audiosNotWorking = audiosNotWorking;
appContext.setContext(visitAppContext);
}
}
}

View File

@ -177,7 +177,7 @@ class ApiService {
}
}
static Future<ExportConfigurationDTO?> exportConfiguration(Client client, String configurationId, String language) async {
static Future<ExportConfigurationDTO?> exportConfiguration(Client client, String configurationId, String? language) async {
try {
bool isOnline = await hasNetwork();
if(isOnline) {

View File

@ -1,5 +1,7 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:manager_api/api.dart';
import 'package:mymuseum_visitapp/Helpers/DatabaseHelper.dart';
import 'package:mymuseum_visitapp/Helpers/modelsHelper.dart';
@ -7,14 +9,41 @@ import 'package:mymuseum_visitapp/Models/resourceModel.dart';
import 'package:mymuseum_visitapp/Models/visitContext.dart';
import 'package:mymuseum_visitapp/Services/apiService.dart';
import 'package:mymuseum_visitapp/app_context.dart';
import 'package:mymuseum_visitapp/constants.dart';
class DownloadConfiguration {
static Future<bool> download(AppContext appContext, ConfigurationDTO configuration) async {
static Future<List<ResourceModel>> download(BuildContext buildContext, AppContext appContext, ConfigurationDTO configuration) async {
VisitAppContext visitAppContext = (appContext.getContext() as VisitAppContext);
bool isAllLanguages = false;
List<ResourceModel> audiosNotWorking = [];
if(visitAppContext.isAllLanguages != null) {
isAllLanguages = visitAppContext.isAllLanguages!;
if(isAllLanguages) {
print("Admin here and all download all audios !");
ScaffoldMessenger.of(buildContext).showSnackBar(
const SnackBar(
content: Text("Tous les audios vont être téléchargés"),
backgroundColor: kMainColor),
);
}
}
print("Start export configuration to store it locally");
ExportConfigurationDTO? exportConfigurationDTO;
try{
exportConfigurationDTO = await ApiService.exportConfiguration(appContext.clientAPI, configuration.id!, isAllLanguages ? null : visitAppContext.language!);
} catch(e) {
print("Erreur lors du téléchargement de la visite");
print(e);
}
print("COUCOUCOU IIIIINNNN");
ExportConfigurationDTO? exportConfigurationDTO = await ApiService.exportConfiguration(appContext.clientAPI, configuration.id!, (appContext.getContext() as VisitAppContext).language!);
if(exportConfigurationDTO != null) {
// Delete all from local DB ref to this configurationId then add it all
await DatabaseHelper.instance.insert(DatabaseTableType.configurations, ModelsHelper.configurationToMap(configuration));
@ -84,25 +113,11 @@ class DownloadConfiguration {
}
}
}
var audioIdArticle = articleDTO.audioIds!.where((audioId) => audioId.language == currentLanguage);
if(audioIdArticle.isNotEmpty && audioIdArticle.first.value != null)
{
usedImageOrAudioIds.add(audioIdArticle.first.value!);
var audioData = exportConfigurationDTO.resources!.where((element) => element.id == audioIdArticle.first.value);
if(audioData.isNotEmpty) {
ResourceModel resourceModel = ResourceModel(id: audioData.first.id, source: "", data: audioData.first.data, type: audioData.first.type);
try {
await DatabaseHelper.instance.insert(DatabaseTableType.resources, resourceModel.toMap());
} catch (e) {
print("We got an issue inserting audio data ${audioData.first.id}");
// Update context with not working audios
VisitAppContext visitAppContext = appContext.getContext() as VisitAppContext;
visitAppContext.audiosNotWorking.add(resourceModel);
visitAppContext.audiosNotWorking = visitAppContext.audiosNotWorking.toSet().toList(); // Remove duplicates
appContext.setContext(visitAppContext);
}
var audioIdsArticle = isAllLanguages ? articleDTO.audioIds! : articleDTO.audioIds!.where((audioId) => audioId.language == currentLanguage);
for(var audioId in audioIdsArticle) {
if(audioId.value != null) {
usedImageOrAudioIds.add(audioId.value!);
audiosNotWorking = await importAudio(visitAppContext, exportConfigurationDTO, audioId.value!, audiosNotWorking);
}
}
}
@ -124,10 +139,34 @@ class DownloadConfiguration {
cleanLocalResources(usedImageOrAudioIds, configuration);
}
}
return true;
return audiosNotWorking;
}
}
Future<List<ResourceModel>> importAudio(VisitAppContext visitAppContext, ExportConfigurationDTO exportConfigurationDTO, String audioId, List<ResourceModel> audiosNotWorking) async {
var audioData = exportConfigurationDTO.resources!.where((element) => element.id == audioId);
if(audioData.isNotEmpty) {
ResourceModel resourceModel = ResourceModel(id: audioData.first.id, source: "", data: audioData.first.data, type: audioData.first.type);
try {
await DatabaseHelper.instance.insert(DatabaseTableType.resources, resourceModel.toMap());
return audiosNotWorking;
} catch (e) {
print("We got an issue inserting audio data ${audioData.first.id}");
resourceModel.label = audioData.first.label;
print(resourceModel.label);
// Update context with not working audios
//VisitAppContext visitAppContext = appContext.getContext() as VisitAppContext;
audiosNotWorking.add(resourceModel);
audiosNotWorking = audiosNotWorking.toSet().toList(); // Remove duplicates
// appContext.setContext(visitAppContext);
return audiosNotWorking;
}
}
return audiosNotWorking;
}
void cleanLocalResources(List<String> usedImageIds, ConfigurationDTO configuration) async {
List<Map<String, dynamic>> resourcesInDB = await DatabaseHelper.instance.queryAllRows(DatabaseTableType.resources);

View File

@ -28,7 +28,7 @@ void main() async {
List<SectionRead> articleReadTest = List<SectionRead>.from(await DatabaseHelper.instance.getData(DatabaseTableType.articleRead));
localContext.readSections = articleReadTest;
} else {
localContext = VisitAppContext(language: "FR", id: "UserId_Init", instanceId: "633ee379d9405f32f166f047");
localContext = VisitAppContext(language: "FR", id: "UserId_Init", instanceId: "633ee379d9405f32f166f047", isAdmin: false, isAllLanguages: false);
DatabaseHelper.instance.insert(DatabaseTableType.main, localContext.toMap());
List<SectionRead> articleReadTest = List<SectionRead>.from(await DatabaseHelper.instance.getData(DatabaseTableType.articleRead));