⬆️ Support latest Paperclip

This commit is contained in:
LittleSheep 2024-07-29 18:06:38 +08:00
parent 3db6850d89
commit 8ab3ca5633
4 changed files with 11 additions and 97 deletions

View File

@ -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),

View File

@ -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);

View File

@ -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(

View File

@ -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;