diff --git a/lib/providers/content/attachment.dart b/lib/providers/content/attachment.dart index 3d1c98d..fb6d3d4 100644 --- a/lib/providers/content/attachment.dart +++ b/lib/providers/content/attachment.dart @@ -31,23 +31,27 @@ Future calculateFileSha256(File file) async { return await calculateBytesSha256(bytes); } -Future calculateDataAspectRatio(Uint8List data) async { +Future> calculateImageData(Uint8List data) async { if (PlatformInfo.isWeb) { - return 1; + return {}; } final decoder = await Isolate.run(() => img.findDecoderForData(data)); - if (decoder == null) return 1; + if (decoder == null) return {}; final image = await Isolate.run(() => decoder.decode(data)); - if (image == null) return 1; - return image.width / image.height; + if (image == null) return {}; + return { + 'width': image.width, + 'height': image.height, + 'ratio': image.width / image.height + }; } -Future calculateFileAspectRatio(File file) async { +Future> calculateImageMetaFromFile(File file) async { if (PlatformInfo.isWeb) { - return 1; + return {}; } final bytes = await Isolate.run(() => file.readAsBytesSync()); - return await calculateDataAspectRatio(bytes); + return await calculateImageData(bytes); } class AttachmentProvider extends GetConnect { @@ -75,8 +79,12 @@ class AttachmentProvider extends GetConnect { } Future createAttachment( - Uint8List data, String path, String hash, String usage, - {double? ratio}) async { + Uint8List data, + String path, + String hash, + String usage, + Map? metadata, + ) async { final AuthProvider auth = Get.find(); if (!await auth.isAuthorized) throw Exception('unauthorized'); @@ -104,9 +112,7 @@ class AttachmentProvider extends GetConnect { 'hash': hash, 'usage': usage, if (mimetypeOverride != null) 'mimetype': mimetypeOverride, - 'metadata': jsonEncode({ - if (ratio != null) 'ratio': ratio, - }), + 'metadata': jsonEncode(metadata), }); final resp = await client.post('/attachments', payload); if (resp.statusCode != 200) { diff --git a/lib/screens/account/personalize.dart b/lib/screens/account/personalize.dart index d17c0ee..7ecfce8 100644 --- a/lib/screens/account/personalize.dart +++ b/lib/screens/account/personalize.dart @@ -87,12 +87,14 @@ class _PersonalizeScreenState extends State { try { final file = File(image.path); final hash = await calculateFileSha256(file); + final meta = await calculateImageMetaFromFile(file); + attachResp = await provider.createAttachment( await file.readAsBytes(), file.path, hash, 'p.$position', - ratio: await calculateFileAspectRatio(file), + {...meta}, ); } catch (e) { setState(() => _isBusy = false); diff --git a/lib/widgets/attachments/attachment_publish.dart b/lib/widgets/attachments/attachment_publish.dart index 51cce2b..b2e0f53 100644 --- a/lib/widgets/attachments/attachment_publish.dart +++ b/lib/widgets/attachments/attachment_publish.dart @@ -54,13 +54,14 @@ class _AttachmentPublishPopupState extends State { for (final media in medias) { final file = File(media.path); final hash = await calculateFileSha256(file); + final meta = await calculateImageMetaFromFile(file); try { await uploadAttachment( await file.readAsBytes(), file.path, hash, - ratio: await calculateFileAspectRatio(file), + {...meta}, ); } catch (err) { context.showErrorDialog(err); @@ -81,11 +82,11 @@ class _AttachmentPublishPopupState extends State { final file = File(media.path); final hash = await calculateFileSha256(file); - const ratio = 16 / 9; try { - await uploadAttachment(await file.readAsBytes(), file.path, hash, - ratio: ratio); + await uploadAttachment(await file.readAsBytes(), file.path, hash, { + 'ratio': 16 / 9, + }); } catch (err) { context.showErrorDialog(err); } @@ -97,8 +98,9 @@ class _AttachmentPublishPopupState extends State { final AuthProvider auth = Get.find(); if (!await auth.isAuthorized) return; - FilePickerResult? result = - await FilePicker.platform.pickFiles(allowMultiple: true); + FilePickerResult? result = await FilePicker.platform.pickFiles( + allowMultiple: true, + ); if (result == null) return; setState(() => _isBusy = true); @@ -108,7 +110,7 @@ class _AttachmentPublishPopupState extends State { for (final file in files) { final hash = await calculateFileSha256(file); try { - await uploadAttachment(await file.readAsBytes(), file.path, hash); + await uploadAttachment(await file.readAsBytes(), file.path, hash, null); } catch (err) { context.showErrorDialog(err); } @@ -131,23 +133,20 @@ class _AttachmentPublishPopupState extends State { setState(() => _isBusy = true); - double? ratio; + Map metadata; final file = File(media.path); final hash = await calculateFileSha256(file); if (isVideo) { - ratio = 16 / 9; + metadata = {'ratio': 16 / 9}; } else { - ratio = await calculateFileAspectRatio(file); + metadata = await calculateImageMetaFromFile(file); } try { - await uploadAttachment( - await file.readAsBytes(), - file.path, - hash, - ratio: ratio, - ); + await uploadAttachment(await file.readAsBytes(), file.path, hash, { + ...metadata, + }); } catch (err) { context.showErrorDialog(err); } @@ -162,14 +161,14 @@ class _AttachmentPublishPopupState extends State { setState(() => _isBusy = true); final hash = await calculateBytesSha256(data); - final ratio = await calculateDataAspectRatio(data); - uploadAttachment(data, 'pasted image', hash, ratio: ratio); + final meta = await calculateImageData(data); + uploadAttachment(data, 'Pasted Image', hash, {...meta}); setState(() => _isBusy = false); } Future uploadAttachment(Uint8List data, String path, String hash, - {double? ratio}) async { + Map? metadata) async { final AttachmentProvider provider = Get.find(); try { context.showSnackbar((PlatformInfo.isWeb @@ -181,7 +180,7 @@ class _AttachmentPublishPopupState extends State { path, hash, widget.usage, - ratio: ratio, + metadata, ); var result = Attachment.fromJson(resp.body); setState(() => _attachments.add(result)); @@ -281,11 +280,14 @@ class _AttachmentPublishPopupState extends State { for (final file in detail.files) { final data = await file.readAsBytes(); final hash = await calculateBytesSha256(data); - double? ratio; + + Map meta = {}; + if (file.mimeType?.split('/').firstOrNull == 'image') { - ratio = await calculateDataAspectRatio(data); + meta = await calculateImageData(data); } - uploadAttachment(data, file.path, hash, ratio: ratio); + + uploadAttachment(data, file.path, hash, {...meta}); } setState(() => _isBusy = false); }, @@ -347,9 +349,8 @@ class _AttachmentPublishPopupState extends State { overflow: TextOverflow.ellipsis, maxLines: 1, style: const TextStyle( - fontWeight: FontWeight.bold, - fontFamily: 'monospace' - ), + fontWeight: FontWeight.bold, + fontFamily: 'monospace'), ), Text( '${fileType[0].toUpperCase()}${fileType.substring(1)} ยท ${formatBytes(element.size)}', @@ -506,7 +507,7 @@ class _AttachmentEditorDialogState extends State { _isMature = widget.item.isMature; _altController.text = widget.item.alt; - if (['image', 'video'].contains(widget.item.mimetype.split('/').first)) { + if (['image', 'video'].contains(widget.item.mimetype.split('/').firstOrNull)) { _ratioController.text = widget.item.metadata?['ratio']?.toString() ?? 1.toString(); _hasAspectRatio = true;