workouttest_app/lib/library/image_cache.dart
2021-04-02 11:42:26 +02:00

151 lines
4.4 KiB
Dart

import 'dart:convert';
import 'dart:typed_data';
import 'package:aitrainer_app/service/logging.dart';
import 'package:aitrainer_app/util/not_found_exception.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:aitrainer_app/library//network_image_to_byte.dart';
import 'dart:collection';
class ImageCache with Logging {
static final ImageCache _singleton = ImageCache._internal();
final LinkedHashMap<String, String> _images = LinkedHashMap();
final LinkedHashMap<String, bool> _imageMap = LinkedHashMap();
var downloadSize = 0;
// Create storage
final storage = FlutterSecureStorage();
factory ImageCache() {
return _singleton;
}
ImageCache._internal();
LinkedHashMap getImageList() => _images;
void clearImageList() => _images.clear();
bool existsImageInMap(int id, String url) {
final String imageKey = generateMd5(url + "_" + id.toString());
return _imageMap[imageKey] != null && _imageMap[imageKey] == true;
}
String? getImageString(int id, String url) {
final String imageKey = generateMd5(url + "_" + id.toString());
return _images[imageKey];
}
Future<void> putImageToList(int id, String url) async {
final String imageKey = generateMd5(url + "_" + id.toString());
// get from storage
final String imageString = (await getImageAs64BaseString(id, url))!;
_images[imageKey] = imageString;
_imageMap[imageKey] = true;
/* final String imageString = await getImageAs64BaseString(id, url);
if (imageString != null) {
_imageMap[imageKey] = imageString;
_imageDown[imageKey] = true;
}
}
_images[imageKey] = imageString;
_imageMap[imageKey] = true; */
}
Future<void> saveImageToPrefs(String key, String value) async {
//log(" save the key " + key);
await storage.write(key: key, value: value);
return;
}
Future<void> emptyPrefs() async {
await storage.deleteAll();
return;
}
Future<String?> loadImageFromPrefs(String key) async {
String? value = await storage.read(key: key);
return value;
}
Future<bool> existImageInPrefs(String key) async {
return await storage.containsKey(key: key);
}
// encodes bytes list as string
static String base64String(Uint8List data) {
return base64Encode(data);
}
// decode bytes from a string
Image imageFrom64BaseString(String base64String) {
return Image.memory(
base64Decode(base64String),
fit: BoxFit.fill,
);
}
Future<Image?> getImage(int id, String name) async {
if (name.length == 0) {
return null;
}
final String imageKey = generateMd5(name + "_" + id.toString());
final String? imageString = await storage.read(key: imageKey);
if (imageString == null) {
return null;
}
final Image image = imageFrom64BaseString(imageString);
return image;
}
Future<String?> getImageAs64BaseString(int id, String name) async {
final String imageKey = generateMd5(name + "_" + id.toString());
String? imageString;
if (await storage.containsKey(key: imageKey)) {
//log(" .. get from storage");
imageString = await storage.read(key: imageKey);
} else {
imageString = (await downloadAndSaveImage(id, name))!;
//log(" .. downloaded");
}
return imageString;
}
Future<String?> downloadAndSaveImage(int id, String url) async {
final String imageKey = generateMd5(url + "_" + id.toString());
if (!await existImageInPrefs(imageKey)) {
try {
if (url.contains("http")) {
log(" ... direct download " + url);
Uint8List byteImage = await networkImageToByte(url);
this.downloadSize += byteImage.length;
final String imageAsString = base64String(byteImage);
ImageCache().saveImageToPrefs(imageKey, imageAsString);
return imageAsString;
}
} on NotFoundException catch (_) {
print(url + " not found");
} on Exception catch (e) {
print(e);
}
} else {
//log(" .. from storage");
//await storage.read(key: imageKey);
}
return null;
}
String generateMd5(String input) {
String converted = input.replaceAll(RegExp(r'\.'), 'a');
converted = converted.replaceAll(RegExp(r'\/'), 'b');
converted = converted.replaceAll(RegExp(r':'), 'c');
//print("key: " + converted);
return converted;
}
}