Rich text editor for Flutter
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

105 lines
2.5 KiB

import 'dart:io' show File;
import 'package:flutter/foundation.dart' show Uint8List;
import 'package:gal/gal.dart';
import 'package:http/http.dart' as http;
// I would like to orgnize the project structure and the code more
// but here I don't want to change too much since that is a community project
RegExp _base64 = RegExp(
r'^(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=|[A-Za-z0-9+\/]{4})$',
);
bool isBase64(String str) {
return _base64.hasMatch(str);
}
bool isHttpBasedUrl(String url) {
try {
final uri = Uri.parse(url.trim());
return uri.isScheme('HTTP') || uri.isScheme('HTTPS');
} catch (_) {
return false;
}
}
bool isYouTubeUrl(String videoUrl) {
try {
final uri = Uri.parse(videoUrl);
return uri.host == 'www.youtube.com' ||
uri.host == 'youtube.com' ||
uri.host == 'youtu.be';
} catch (_) {
return false;
}
}
bool isImageBase64(String imageUrl) {
return !isHttpBasedUrl(imageUrl) && isBase64(imageUrl);
}
enum SaveImageResultMethod { network, localStorage }
class _SaveImageResult {
const _SaveImageResult({required this.isSuccess, required this.method});
final bool isSuccess;
final SaveImageResultMethod method;
}
Future<_SaveImageResult> saveImage(String imageUrl) async {
final imageFile = File(imageUrl);
final hasPermission = await Gal.hasAccess();
final imageExistsLocally = await imageFile.exists();
if (!hasPermission) {
await Gal.requestAccess();
}
if (!imageExistsLocally) {
final success = await _saveNetworkImageToLocal(imageUrl);
return _SaveImageResult(
isSuccess: success,
method: SaveImageResultMethod.network,
);
}
final success = await _saveImageLocally(imageFile);
return _SaveImageResult(
isSuccess: success,
method: SaveImageResultMethod.localStorage,
);
}
Future<bool> _saveNetworkImageToLocal(String imageUrl) async {
try {
final response = await http.get(
Uri.parse(imageUrl),
);
if (response.statusCode != 200) {
return false;
}
final imageBytes = response.bodyBytes;
await Gal.putImageBytes(imageBytes);
return true;
} catch (e) {
return false;
}
}
Future<Uint8List> _convertFileToUint8List(File file) async {
try {
final uint8list = await file.readAsBytes();
return uint8list;
} catch (e) {
return Uint8List(0);
}
}
Future<bool> _saveImageLocally(File imageFile) async {
try {
final imageBytes = await _convertFileToUint8List(imageFile);
await Gal.putImageBytes(imageBytes);
return true;
} catch (e) {
return false;
}
}