Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 16 additions & 5 deletions lib/services/ui/attachments_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import 'package:exif/exif.dart';
import 'package:file_picker/file_picker.dart' hide PlatformFile;
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_image_compress/flutter_image_compress.dart';
import 'package:get/get.dart';
import 'package:image_size_getter/file_input.dart';
Expand All @@ -26,6 +27,7 @@ import 'package:vcf_dart/vcf_dart.dart';
import 'package:video_thumbnail/video_thumbnail.dart';

AttachmentsService as = Get.isRegistered<AttachmentsService>() ? Get.find<AttachmentsService>() : Get.put(AttachmentsService());
const MethodChannel _desktopMediaChannel = MethodChannel('com.bluebubbles.messaging');

class AttachmentsService extends GetxService {

Expand Down Expand Up @@ -346,19 +348,28 @@ class AttachmentsService extends GetxService {
}

// Handle getting heic and tiff images
if (attachment.mimeType!.contains('image/hei') && !kIsDesktop) {
if (attachment.mimeType!.contains('image/hei')) {
if (await File("$filePath.png").exists()) {
originalFile = File("$filePath.png");
} else {
try {
if (onlyFetchData) {
if (kIsDesktop && Platform.isLinux) {
await _desktopMediaChannel.invokeMethod("decode-heif", {
"file": filePath,
"output": "$filePath.png",
});
originalFile = File("$filePath.png");
if (onlyFetchData) {
return await originalFile.readAsBytes();
}
} else if (!kIsDesktop && onlyFetchData) {
return await FlutterImageCompress.compressWithFile(
filePath,
format: CompressFormat.png,
keepExif: true,
quality: isPreview ? 25 : 100,
);
} else {
} else if (!kIsDesktop) {
final file = await FlutterImageCompress.compressAndGetFile(
filePath,
"$filePath.png",
Expand Down Expand Up @@ -422,7 +433,7 @@ class AttachmentsService extends GetxService {
}
} else if (attachment.mimeStart == "image") {
try {
Size size = await getImageSizing(filePath, attachment);
Size size = await getImageSizing(originalFile.path, attachment);
if (size.width != 0 && size.height != 0) {
attachment.width = size.width.toInt();
attachment.height = size.height.toInt();
Expand Down Expand Up @@ -451,4 +462,4 @@ class AttachmentsService extends GetxService {

return previewData;
}
}
}
69 changes: 69 additions & 0 deletions linux/my_application.cc
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#include "my_application.h"

#include <flutter_linux/flutter_linux.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <cstring>
#ifdef GDK_WINDOWING_X11
#include <gdk/gdkx.h>
#endif
Expand All @@ -12,10 +14,68 @@
struct _MyApplication {
GtkApplication parent_instance;
char** dart_entrypoint_arguments;
FlMethodChannel* channel;
};

G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION)

static void respond_with_error(FlMethodCall* method_call,
const gchar* code,
const gchar* message) {
g_autoptr(FlMethodResponse) response = FL_METHOD_RESPONSE(
fl_method_error_response_new(code, message, nullptr));
fl_method_call_respond(method_call, response, nullptr);
}

static void method_call_cb(FlMethodChannel* channel,
FlMethodCall* method_call,
gpointer user_data) {
(void)channel;
(void)user_data;
const gchar* method = fl_method_call_get_name(method_call);

if (strcmp(method, "decode-heif") != 0) {
g_autoptr(FlMethodResponse) response = FL_METHOD_RESPONSE(
fl_method_not_implemented_response_new());
fl_method_call_respond(method_call, response, nullptr);
return;
}

FlValue* args = fl_method_call_get_args(method_call);
if (args == nullptr || fl_value_get_type(args) != FL_VALUE_TYPE_MAP) {
respond_with_error(method_call, "bad-args", "Expected argument map");
return;
}

FlValue* file_value = fl_value_lookup_string(args, "file");
FlValue* output_value = fl_value_lookup_string(args, "output");
if (file_value == nullptr || output_value == nullptr ||
fl_value_get_type(file_value) != FL_VALUE_TYPE_STRING ||
fl_value_get_type(output_value) != FL_VALUE_TYPE_STRING) {
respond_with_error(method_call, "bad-args", "Missing file or output path");
return;
}

const gchar* input_path = fl_value_get_string(file_value);
const gchar* output_path = fl_value_get_string(output_value);

g_autoptr(GError) error = nullptr;
g_autoptr(GdkPixbuf) pixbuf = gdk_pixbuf_new_from_file(input_path, &error);
if (pixbuf == nullptr) {
respond_with_error(method_call, "decode-failed", error->message);
return;
}

if (!gdk_pixbuf_save(pixbuf, output_path, "png", &error, nullptr)) {
respond_with_error(method_call, "encode-failed", error->message);
return;
}

g_autoptr(FlMethodResponse) response =
FL_METHOD_RESPONSE(fl_method_success_response_new(nullptr));
fl_method_call_respond(method_call, response, nullptr);
}

// Implements GApplication::activate.
static void my_application_activate(GApplication* application) {
MyApplication* self = MY_APPLICATION(application);
Expand Down Expand Up @@ -63,6 +123,14 @@ static void my_application_activate(GApplication* application) {

fl_register_plugins(FL_PLUGIN_REGISTRY(view));

FlEngine* engine = fl_view_get_engine(view);
FlBinaryMessenger* messenger = fl_engine_get_binary_messenger(engine);
g_autoptr(FlStandardMethodCodec) codec = fl_standard_method_codec_new();
self->channel = fl_method_channel_new(
messenger, "com.bluebubbles.messaging", FL_METHOD_CODEC(codec));
fl_method_channel_set_method_call_handler(self->channel, method_call_cb,
self, nullptr);

gtk_widget_grab_focus(GTK_WIDGET(view));
}

Expand All @@ -89,6 +157,7 @@ static gboolean my_application_local_command_line(GApplication* application, gch
static void my_application_dispose(GObject* object) {
MyApplication* self = MY_APPLICATION(object);
g_clear_pointer(&self->dart_entrypoint_arguments, g_strfreev);
g_clear_object(&self->channel);
G_OBJECT_CLASS(my_application_parent_class)->dispose(object);
}

Expand Down