⬆️ Support latest Paperclip
This commit is contained in:
parent
3db6850d89
commit
8ab3ca5633
@ -1,59 +1,11 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:io';
|
|
||||||
import 'dart:isolate';
|
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:crypto/crypto.dart';
|
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:path/path.dart';
|
import 'package:path/path.dart';
|
||||||
import 'package:solian/models/attachment.dart';
|
import 'package:solian/models/attachment.dart';
|
||||||
import 'package:solian/platform.dart';
|
|
||||||
import 'package:solian/providers/auth.dart';
|
import 'package:solian/providers/auth.dart';
|
||||||
import 'package:solian/services.dart';
|
import 'package:solian/services.dart';
|
||||||
import 'package:image/image.dart' as img;
|
|
||||||
|
|
||||||
Future<String> calculateBytesSha256(Uint8List data) async {
|
|
||||||
Digest digest;
|
|
||||||
if (PlatformInfo.isWeb) {
|
|
||||||
digest = sha256.convert(data);
|
|
||||||
} else {
|
|
||||||
digest = await Isolate.run(() => sha256.convert(data));
|
|
||||||
}
|
|
||||||
return digest.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<String> calculateFileSha256(File file) async {
|
|
||||||
Uint8List bytes;
|
|
||||||
if (PlatformInfo.isWeb) {
|
|
||||||
bytes = await file.readAsBytes();
|
|
||||||
} else {
|
|
||||||
bytes = await Isolate.run(() => file.readAsBytesSync());
|
|
||||||
}
|
|
||||||
return await calculateBytesSha256(bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<Map<String, dynamic>> calculateImageData(Uint8List data) async {
|
|
||||||
if (PlatformInfo.isWeb) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
final decoder = await Isolate.run(() => img.findDecoderForData(data));
|
|
||||||
if (decoder == null) return {};
|
|
||||||
final image = await Isolate.run(() => decoder.decode(data));
|
|
||||||
if (image == null) return {};
|
|
||||||
return {
|
|
||||||
'width': image.width,
|
|
||||||
'height': image.height,
|
|
||||||
'ratio': image.width / image.height
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<Map<String, dynamic>> calculateImageMetaFromFile(File file) async {
|
|
||||||
if (PlatformInfo.isWeb) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
final bytes = await Isolate.run(() => file.readAsBytesSync());
|
|
||||||
return await calculateImageData(bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
class AttachmentProvider extends GetConnect {
|
class AttachmentProvider extends GetConnect {
|
||||||
static Map<String, String> mimetypeOverrides = {
|
static Map<String, String> mimetypeOverrides = {
|
||||||
@ -79,7 +31,6 @@ class AttachmentProvider extends GetConnect {
|
|||||||
if (result.destination != 0 && result.isAnalyzed) {
|
if (result.destination != 0 && result.isAnalyzed) {
|
||||||
_cachedResponses[id] = result;
|
_cachedResponses[id] = result;
|
||||||
}
|
}
|
||||||
print(result);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,7 +40,6 @@ class AttachmentProvider extends GetConnect {
|
|||||||
Future<Response> createAttachment(
|
Future<Response> createAttachment(
|
||||||
Uint8List data,
|
Uint8List data,
|
||||||
String path,
|
String path,
|
||||||
String hash,
|
|
||||||
String usage,
|
String usage,
|
||||||
Map<String, dynamic>? metadata,
|
Map<String, dynamic>? metadata,
|
||||||
) async {
|
) async {
|
||||||
@ -117,7 +67,6 @@ class AttachmentProvider extends GetConnect {
|
|||||||
final payload = FormData({
|
final payload = FormData({
|
||||||
'alt': fileAlt,
|
'alt': fileAlt,
|
||||||
'file': filePayload,
|
'file': filePayload,
|
||||||
'hash': hash,
|
|
||||||
'usage': usage,
|
'usage': usage,
|
||||||
if (mimetypeOverride != null) 'mimetype': mimetypeOverride,
|
if (mimetypeOverride != null) 'mimetype': mimetypeOverride,
|
||||||
'metadata': jsonEncode(metadata),
|
'metadata': jsonEncode(metadata),
|
||||||
|
@ -86,15 +86,11 @@ class _PersonalizeScreenState extends State<PersonalizeScreen> {
|
|||||||
Response? attachResp;
|
Response? attachResp;
|
||||||
try {
|
try {
|
||||||
final file = File(image.path);
|
final file = File(image.path);
|
||||||
final hash = await calculateFileSha256(file);
|
|
||||||
final meta = await calculateImageMetaFromFile(file);
|
|
||||||
|
|
||||||
attachResp = await provider.createAttachment(
|
attachResp = await provider.createAttachment(
|
||||||
await file.readAsBytes(),
|
await file.readAsBytes(),
|
||||||
file.path,
|
file.path,
|
||||||
hash,
|
|
||||||
'p.$position',
|
'p.$position',
|
||||||
{...meta},
|
null
|
||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
setState(() => _isBusy = false);
|
setState(() => _isBusy = false);
|
||||||
|
@ -60,11 +60,9 @@ class _AttachmentListFullScreenState extends State<AttachmentListFullScreen> {
|
|||||||
DismissiblePageDismissDirection.multi: 0.05,
|
DismissiblePageDismissDirection.multi: 0.05,
|
||||||
},
|
},
|
||||||
onDragStart: () {
|
onDragStart: () {
|
||||||
print('start dragging');
|
|
||||||
setState(() => _showDetails = false);
|
setState(() => _showDetails = false);
|
||||||
},
|
},
|
||||||
onDragEnd: () {
|
onDragEnd: () {
|
||||||
print('stop dragging');
|
|
||||||
setState(() => _showDetails = true);
|
setState(() => _showDetails = true);
|
||||||
},
|
},
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
|
@ -53,15 +53,11 @@ class _AttachmentPublishPopupState extends State<AttachmentPublishPopup> {
|
|||||||
|
|
||||||
for (final media in medias) {
|
for (final media in medias) {
|
||||||
final file = File(media.path);
|
final file = File(media.path);
|
||||||
final hash = await calculateFileSha256(file);
|
|
||||||
final meta = await calculateImageMetaFromFile(file);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await uploadAttachment(
|
await uploadAttachment(
|
||||||
await file.readAsBytes(),
|
await file.readAsBytes(),
|
||||||
file.path,
|
file.path,
|
||||||
hash,
|
null,
|
||||||
{...meta},
|
|
||||||
);
|
);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
context.showErrorDialog(err);
|
context.showErrorDialog(err);
|
||||||
@ -81,12 +77,9 @@ class _AttachmentPublishPopupState extends State<AttachmentPublishPopup> {
|
|||||||
setState(() => _isBusy = true);
|
setState(() => _isBusy = true);
|
||||||
|
|
||||||
final file = File(media.path);
|
final file = File(media.path);
|
||||||
final hash = await calculateFileSha256(file);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await uploadAttachment(await file.readAsBytes(), file.path, hash, {
|
await uploadAttachment(await file.readAsBytes(), file.path, null);
|
||||||
'ratio': 16 / 9,
|
|
||||||
});
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
context.showErrorDialog(err);
|
context.showErrorDialog(err);
|
||||||
}
|
}
|
||||||
@ -108,9 +101,8 @@ class _AttachmentPublishPopupState extends State<AttachmentPublishPopup> {
|
|||||||
List<File> files = result.paths.map((path) => File(path!)).toList();
|
List<File> files = result.paths.map((path) => File(path!)).toList();
|
||||||
|
|
||||||
for (final file in files) {
|
for (final file in files) {
|
||||||
final hash = await calculateFileSha256(file);
|
|
||||||
try {
|
try {
|
||||||
await uploadAttachment(await file.readAsBytes(), file.path, hash, null);
|
await uploadAttachment(await file.readAsBytes(), file.path, null);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
context.showErrorDialog(err);
|
context.showErrorDialog(err);
|
||||||
}
|
}
|
||||||
@ -133,20 +125,9 @@ class _AttachmentPublishPopupState extends State<AttachmentPublishPopup> {
|
|||||||
|
|
||||||
setState(() => _isBusy = true);
|
setState(() => _isBusy = true);
|
||||||
|
|
||||||
Map<String, dynamic> metadata;
|
|
||||||
final file = File(media.path);
|
final file = File(media.path);
|
||||||
final hash = await calculateFileSha256(file);
|
|
||||||
|
|
||||||
if (isVideo) {
|
|
||||||
metadata = {'ratio': 16 / 9};
|
|
||||||
} else {
|
|
||||||
metadata = await calculateImageMetaFromFile(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await uploadAttachment(await file.readAsBytes(), file.path, hash, {
|
await uploadAttachment(await file.readAsBytes(), file.path, null);
|
||||||
...metadata,
|
|
||||||
});
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
context.showErrorDialog(err);
|
context.showErrorDialog(err);
|
||||||
}
|
}
|
||||||
@ -160,15 +141,13 @@ class _AttachmentPublishPopupState extends State<AttachmentPublishPopup> {
|
|||||||
|
|
||||||
setState(() => _isBusy = true);
|
setState(() => _isBusy = true);
|
||||||
|
|
||||||
final hash = await calculateBytesSha256(data);
|
uploadAttachment(data, 'Pasted Image', null);
|
||||||
final meta = await calculateImageData(data);
|
|
||||||
uploadAttachment(data, 'Pasted Image', hash, {...meta});
|
|
||||||
|
|
||||||
setState(() => _isBusy = false);
|
setState(() => _isBusy = false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> uploadAttachment(Uint8List data, String path, String hash,
|
Future<void> uploadAttachment(
|
||||||
Map<String, dynamic>? metadata) async {
|
Uint8List data, String path, Map<String, dynamic>? metadata) async {
|
||||||
final AttachmentProvider provider = Get.find();
|
final AttachmentProvider provider = Get.find();
|
||||||
try {
|
try {
|
||||||
context.showSnackbar((PlatformInfo.isWeb
|
context.showSnackbar((PlatformInfo.isWeb
|
||||||
@ -178,7 +157,6 @@ class _AttachmentPublishPopupState extends State<AttachmentPublishPopup> {
|
|||||||
final resp = await provider.createAttachment(
|
final resp = await provider.createAttachment(
|
||||||
data,
|
data,
|
||||||
path,
|
path,
|
||||||
hash,
|
|
||||||
widget.usage,
|
widget.usage,
|
||||||
metadata,
|
metadata,
|
||||||
);
|
);
|
||||||
@ -279,15 +257,7 @@ class _AttachmentPublishPopupState extends State<AttachmentPublishPopup> {
|
|||||||
setState(() => _isBusy = true);
|
setState(() => _isBusy = true);
|
||||||
for (final file in detail.files) {
|
for (final file in detail.files) {
|
||||||
final data = await file.readAsBytes();
|
final data = await file.readAsBytes();
|
||||||
final hash = await calculateBytesSha256(data);
|
uploadAttachment(data, file.path, null);
|
||||||
|
|
||||||
Map<String, dynamic> meta = {};
|
|
||||||
|
|
||||||
if (file.mimeType?.split('/').firstOrNull == 'image') {
|
|
||||||
meta = await calculateImageData(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
uploadAttachment(data, file.path, hash, {...meta});
|
|
||||||
}
|
}
|
||||||
setState(() => _isBusy = false);
|
setState(() => _isBusy = false);
|
||||||
},
|
},
|
||||||
@ -507,7 +477,8 @@ class _AttachmentEditorDialogState extends State<AttachmentEditorDialog> {
|
|||||||
_isMature = widget.item.isMature;
|
_isMature = widget.item.isMature;
|
||||||
_altController.text = widget.item.alt;
|
_altController.text = widget.item.alt;
|
||||||
|
|
||||||
if (['image', 'video'].contains(widget.item.mimetype.split('/').firstOrNull)) {
|
if (['image', 'video']
|
||||||
|
.contains(widget.item.mimetype.split('/').firstOrNull)) {
|
||||||
_ratioController.text =
|
_ratioController.text =
|
||||||
widget.item.metadata?['ratio']?.toString() ?? 1.toString();
|
widget.item.metadata?['ratio']?.toString() ?? 1.toString();
|
||||||
_hasAspectRatio = true;
|
_hasAspectRatio = true;
|
||||||
|
Loading…
Reference in New Issue
Block a user