diff --git a/lib/widgets/compose_box.dart b/lib/widgets/compose_box.dart index aabf592dae..2e7235405d 100644 --- a/lib/widgets/compose_box.dart +++ b/lib/widgets/compose_box.dart @@ -4,7 +4,8 @@ import 'package:app_settings/app_settings.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:mime/mime.dart'; - +import 'package:path_provider/path_provider.dart'; +import 'package:image/image.dart' as img; import '../api/exception.dart'; import '../api/model/model.dart'; import '../api/route/messages.dart'; @@ -21,7 +22,6 @@ import 'inset_shadow.dart'; import 'store.dart'; import 'text.dart'; import 'theme.dart'; - /// Compose-box styles that differ between light and dark theme. /// /// These styles will animate on theme changes (with help from [lerp]). @@ -966,19 +966,23 @@ class _AttachMediaButton extends _AttachUploadsButton { const _AttachMediaButton({required super.controller}); @override - IconData get icon => ZulipIcons.image; + Future> getFiles(BuildContext context) async { + final files = await _getFilePickerFiles(context, FileType.media); - @override - String tooltip(ZulipLocalizations zulipLocalizations) => - zulipLocalizations.composeBoxAttachMediaTooltip; + // Compress each image file before returning + return Future.wait(files.map((file) async { + File selectedFile = File(file.path); - @override - Future> getFiles(BuildContext context) async { - // TODO(#114): This doesn't give quite the right UI on Android. - return _getFilePickerFiles(context, FileType.media); + // Compress the image + File compressedFile = await compressImage(selectedFile); + + // Create a new _File object with the compressed file path + return _File(path: compressedFile.path, name: file.name, size: compressedFile.lengthSync()); + })); } } + class _AttachFromCameraButton extends _AttachUploadsButton { const _AttachFromCameraButton({required super.controller}); @@ -1000,8 +1004,17 @@ class _AttachFromCameraButton extends _AttachUploadsButton { // so just stick with images for now. We could add another button for // videos, but we don't want too many buttons. result = await ZulipBinding.instance.pickImage( - source: ImageSource.camera, requestFullMetadata: false); - } catch (e) { + source: ImageSource.camera, requestFullMetadata: false); + +if (result != null && result.path != null) { + File selectedFile = File(result.path); + + // Compress the image before using it + File compressedFile = await compressImage(selectedFile); + + // Use compressedFile instead of selectedFile + uploadImage(compressedFile); +} catch (e) { if (!context.mounted) return []; if (e is PlatformException && e.code == 'camera_access_denied') { // iOS has a quirk where it will only request the native @@ -1050,7 +1063,7 @@ class _AttachFromCameraButton extends _AttachUploadsButton { )]; } } - +} class _SendButton extends StatefulWidget { const _SendButton({required this.controller, required this.getDestination}); @@ -1597,3 +1610,15 @@ class _ComposeBoxState extends State with PerAccountStoreAwareStateM return _ComposeBoxContainer(body: body, banner: null); } } +Future compressImage(File imageFile) async { + final int maxSize = 10 * 1024 * 1024; // 10MB + if (imageFile.lengthSync() > maxSize) { + img.Image? image = img.decodeImage(imageFile.readAsBytesSync()); + if (image != null) { + List compressedBytes = img.encodeJpg(image, quality: 80); + File compressedFile = File(imageFile.path)..writeAsBytesSync(compressedBytes); + return compressedFile; + } + } + return imageFile; +} \ No newline at end of file diff --git a/packages/zulip_plugin/android/.gradle/8.9/checksums/checksums.lock b/packages/zulip_plugin/android/.gradle/8.9/checksums/checksums.lock new file mode 100644 index 0000000000..10d0ce833f Binary files /dev/null and b/packages/zulip_plugin/android/.gradle/8.9/checksums/checksums.lock differ diff --git a/packages/zulip_plugin/android/.gradle/8.9/dependencies-accessors/gc.properties b/packages/zulip_plugin/android/.gradle/8.9/dependencies-accessors/gc.properties new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/zulip_plugin/android/.gradle/8.9/fileChanges/last-build.bin b/packages/zulip_plugin/android/.gradle/8.9/fileChanges/last-build.bin new file mode 100644 index 0000000000..f76dd238ad Binary files /dev/null and b/packages/zulip_plugin/android/.gradle/8.9/fileChanges/last-build.bin differ diff --git a/packages/zulip_plugin/android/.gradle/8.9/fileHashes/fileHashes.lock b/packages/zulip_plugin/android/.gradle/8.9/fileHashes/fileHashes.lock new file mode 100644 index 0000000000..5d16e4e1aa Binary files /dev/null and b/packages/zulip_plugin/android/.gradle/8.9/fileHashes/fileHashes.lock differ diff --git a/packages/zulip_plugin/android/.gradle/8.9/gc.properties b/packages/zulip_plugin/android/.gradle/8.9/gc.properties new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/zulip_plugin/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/packages/zulip_plugin/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock new file mode 100644 index 0000000000..844953a6cc Binary files /dev/null and b/packages/zulip_plugin/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock differ diff --git a/packages/zulip_plugin/android/.gradle/buildOutputCleanup/cache.properties b/packages/zulip_plugin/android/.gradle/buildOutputCleanup/cache.properties new file mode 100644 index 0000000000..d1a2e454ce --- /dev/null +++ b/packages/zulip_plugin/android/.gradle/buildOutputCleanup/cache.properties @@ -0,0 +1,2 @@ +#Sat Mar 22 09:43:45 IST 2025 +gradle.version=8.9 diff --git a/packages/zulip_plugin/android/.gradle/vcs-1/gc.properties b/packages/zulip_plugin/android/.gradle/vcs-1/gc.properties new file mode 100644 index 0000000000..e69de29bb2 diff --git a/pubspec.yaml b/pubspec.yaml index c95e6fb353..3dec27d53b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -48,6 +48,7 @@ dependencies: html: ^0.15.1 http: ^1.0.0 http_parser: ^4.0.2 + image: ^4.5.4 image_picker: ^1.0.0 json_annotation: ^4.9.0 mime: ^2.0.0 @@ -64,6 +65,7 @@ dependencies: wakelock_plus: ^1.2.8 zulip_plugin: path: ./packages/zulip_plugin + # Keep list sorted when adding dependencies; it helps prevent merge conflicts. dependency_overrides: