import 'dart:convert'; import 'dart:io'; import 'dart:typed_data'; import 'package:archive/archive_io.dart'; import 'package:http/http.dart' as http; import 'package:logging/logging.dart'; import 'package:path_provider/path_provider.dart'; import 'package:fcs/model/firebase_helper.dart'; import 'package:fcs/vo/manual.dart'; import 'package:fcs/vo/setting.dart'; import 'package:path/path.dart' as Path; import 'base_model.dart'; typedef void SlideDataCallback(); class ManualModel extends BaseModel { final log = Logger('ManualModel'); List helps = []; List manuals = []; String version; SlideDataCallback slideDataCallback; List deleteImage = []; String dataDir; void initSetting(Setting setting) async { _download(setting); super.initSetting(setting); } @override logout() async {} Future _download(Setting setting) async { this.dataDir = (await getApplicationDocumentsDirectory()).path; version = setting.helpVersion; var file = File('$dataDir/${setting.helpFileName()}'); if (await file.exists()) { _loadJsonData(); return; } String url = setting.helpURL; var req = await http.Client().get(Uri.parse(url)); File zippedFile = await file.writeAsBytes(req.bodyBytes); File prev = File('$dataDir/manual'); if (await prev.exists()) { await prev.delete(recursive: true); } var bytes = zippedFile.readAsBytesSync(); var archive = ZipDecoder().decodeBytes(bytes); for (var file in archive) { var fileName = '$dataDir/manual/${file.name}'; if (file.isFile) { var outFile = File(fileName); outFile = await outFile.create(recursive: true); await outFile.writeAsBytes(file.content); } } _loadJsonData(); } List getHelpList(bool isBuyer) { return helps.where((h) => isBuyer ? h.isBuyer : true).toList(); } getSlideList(int manIndex) { var slides = helps[manIndex].slides; return slides; } getSlideData(int manIndex, int slideIndex) { var slide; slide = helps[manIndex].slides[slideIndex]; return slide; } Future _loadJsonData() async { try { final directory = await getApplicationDocumentsDirectory(); File file = File('${directory.path}/manual/manual.json'); String contents = await file.readAsString(); var convertArray = jsonDecode(contents); manuals.clear(); convertArray.forEach((item) { var _list = ManualItem.fromMap(item); manuals.add(_list); }); } catch (e) { log.warning("Error:${e.toString()}"); } helps.clear(); helps = manuals.map((e) => ManualItem.clone(e)).toList(); } addManualTitle(ManualItem manualItem) { helps.add(manualItem); notifyListeners(); } uploadStorageManualData(String version, String dir) async { String fileName = 'help-v$version.zip'; var converthelps = []; for (final converthelp in helps) { converthelps.add(converthelp.toJson()); } var json = jsonEncode(converthelps); Directory myDir = new Directory('$dir/manual/img'); List _images; _images = myDir.listSync(recursive: true, followLinks: false); var newImgData = await convertArchiveImgFile(_images, dir, json); File updateImgFile = File('$dir/manual/update'); updateImgFile.writeAsBytesSync(newImgData); var bytes = updateImgFile.readAsBytesSync(); uploadDataZip(bytes, fileName); } convertArchiveImgFile(List imgList, String dataDir, json) async { File file = new File('$dataDir/update'); if (await file.exists()) { await file.delete(recursive: true); } Archive zipArchive = new Archive(); List utf8encoded = utf8.encode(json); ArchiveFile jsonFile = new ArchiveFile("manual.json", utf8encoded.length, utf8encoded); zipArchive.addFile(jsonFile); for (var img in imgList) { String basename = Path.basename(img.path); if (deleteImage.length != 0) { for (var dImgName in deleteImage) { if (dImgName != basename) { Uint8List bytesPhoto = img.readAsBytesSync() as Uint8List; ArchiveFile jsonFile = new ArchiveFile("img/$basename", bytesPhoto.length, bytesPhoto); zipArchive.addFile(jsonFile); } } } else { Uint8List bytesPhoto = img.readAsBytesSync() as Uint8List; ArchiveFile jsonFile = new ArchiveFile("img/$basename", bytesPhoto.length, bytesPhoto); zipArchive.addFile(jsonFile); } } List zipInBytes = new ZipEncoder().encode(zipArchive); file.writeAsBytesSync(zipInBytes); var bytes = file.readAsBytesSync(); return bytes; } uploadDataZip(Uint8List data, String fileName) async { String path = '/ok/img'; String url = await uploadStorageData(path, data, fileName: fileName); } resetManualItems() { helps.clear(); //clone manauals helps = manuals.map((p) => ManualItem.clone(p)).toList(); // return helps.where((h) => isBuyer ? h.isBuyer : true).toList(); } saveInstruction(int manIndex, int slideIndex, int instIndex, Instruction instruction, Instruction oldInst, bool isEng) { if (isEng) { var inst = helps[manIndex].slides[slideIndex].instructions.toList(); instruction.id = oldInst.id; if (inst.length != 0) { helps[manIndex].slides[slideIndex].instructions.remove(oldInst); helps[manIndex] .slides[slideIndex] .instructions .insert(instIndex, instruction); } else { helps[manIndex].slides[slideIndex].instructions.add(instruction); } } else { var inst = helps[manIndex].slides[slideIndex].instructionsmm.toList(); instruction.id = oldInst.id; if (inst.length != 0) { helps[manIndex].slides[slideIndex].instructionsmm.remove(oldInst); helps[manIndex] .slides[slideIndex] .instructionsmm .insert(instIndex, instruction); } else { helps[manIndex].slides[slideIndex].instructionsmm.add(instruction); } } notifyListeners(); } saveSlideData(int manIndex, int slideIndex, SlideData slideData) { helps[manIndex].slides.add(slideData); notifyListeners(); } changeSlideImage(int manIndex, int slideIndex, SlideData slideData) { var oldSlide = helps[manIndex].slides[slideIndex]; helps[manIndex].slides.remove(oldSlide); helps[manIndex].slides.insert(slideIndex, slideData); notifyListeners(); } deleteSlideData(int manIndex, SlideData slideData) { String engImage = slideData.image; String mmImage = slideData.imagemm; deleteImage.add(mmImage); deleteImage.add(engImage); helps[manIndex].slides.remove(slideData); notifyListeners(); } deleteManualItem(ManualItem item) { // if(helps.isEmpty){ // helps = new List(); // } helps.remove(item); notifyListeners(); } }