diff --git a/android/app/build.gradle b/android/app/build.gradle index 273d644c1..3e0f2e483 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -75,28 +75,28 @@ android { productFlavors { joel { dimension "app" - resValue "string", "app_name", "BlueBubbles Dev (Joel)" + resValue "string", "app_name_en", "BlueBubbles Dev (Joel)" resValue "color", "ic_launcher_background", "#4c49de" resValue "string", "file_provider", "com.bluebubbles.messaging.joel.fileprovider" applicationId "com.bluebubbles.messaging.joel" } tanay { dimension "app" - resValue "string", "app_name", "BlueBubbles (Tanay Special Sauce)" + resValue "string", "app_name_en", "BlueBubbles (Tanay Special Sauce)" resValue "color", "ic_launcher_background", "#4c49de" resValue "string", "file_provider", "com.bluebubbles.messaging.tanay.fileprovider" applicationId "com.bluebubbles.messaging.tanay" } alpha { dimension "app" - resValue "string", "app_name", "BlueBubbles (Alpha)" + resValue "string", "app_name_en", "BlueBubbles (Alpha)" resValue "color", "ic_launcher_background", "#49dbde" resValue "string", "file_provider", "com.bluebubbles.messaging.alpha.fileprovider" applicationId "com.bluebubbles.messaging.alpha" } beta { dimension "app" - resValue "string", "app_name", "BlueBubbles (Beta)" + resValue "string", "app_name_en", "BlueBubbles (Beta)" resValue "color", "ic_launcher_background", "#4990de" resValue "string", "file_provider", "com.bluebubbles.messaging.beta.fileprovider" applicationId "com.bluebubbles.messaging.beta" @@ -104,7 +104,7 @@ android { prod { getIsDefault().set(true) dimension "app" - resValue "string", "app_name", "BlueBubbles" + resValue "string", "app_name_en", "BlueBubbles" resValue "color", "ic_launcher_background", "#4990de" resValue "string", "file_provider", "com.bluebubbles.messaging.fileprovider" applicationId "com.bluebubbles.messaging" diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 54723291e..3f02ec39b 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -56,7 +56,7 @@ android:allowBackup="false" android:name=".Application" android:icon="@mipmap/ic_launcher" - android:label="@string/app_name" + android:label="@string/app_name_en" android:appCategory="social" android:requestLegacyExternalStorage="true" android:debuggable="false" diff --git a/android/app/src/main/java/com/bluebubbles/messaging/method_call_handler/handlers/FirebaseAuth.java b/android/app/src/main/java/com/bluebubbles/messaging/method_call_handler/handlers/FirebaseAuth.java index 79ecc25da..eca14432b 100644 --- a/android/app/src/main/java/com/bluebubbles/messaging/method_call_handler/handlers/FirebaseAuth.java +++ b/android/app/src/main/java/com/bluebubbles/messaging/method_call_handler/handlers/FirebaseAuth.java @@ -60,22 +60,26 @@ public void Handle() { .addOnCompleteListener(new OnCompleteListener() { @Override public void onComplete(@NonNull Task task) { - if (task.getResult() == null || !task.isSuccessful()) { - Log.d(TAG, "getInstanceId failed", task.getException()); - try { + try { + if (task.getResult() == null || !task.isSuccessful()) { + Log.d(TAG, "getInstanceId failed", task.getException()); + try { - result.error("Failed to authenticate", "getInstanceId failed", task.getException()); - } catch (IllegalStateException e) { + result.error("Failed to authenticate", "getInstanceId failed", task.getException()); + } catch (IllegalStateException e) { + } + return; } - return; - } - String token = task.getResult(); - Log.d("FCM", "token: " + token); - try { - result.success(token); - } catch (IllegalStateException e) { + String token = task.getResult(); + Log.d("FCM", "token: " + token); + try { + result.success(token); + } catch (IllegalStateException e) { + } + } catch (Exception e) { + result.error("Failed to authenticate", "FCM not available!", ""); } } }); diff --git a/android/app/src/main/java/com/bluebubbles/messaging/method_call_handler/handlers/IncomingFaceTimeNotification.java b/android/app/src/main/java/com/bluebubbles/messaging/method_call_handler/handlers/IncomingFaceTimeNotification.java index a704a4f26..3c470f174 100644 --- a/android/app/src/main/java/com/bluebubbles/messaging/method_call_handler/handlers/IncomingFaceTimeNotification.java +++ b/android/app/src/main/java/com/bluebubbles/messaging/method_call_handler/handlers/IncomingFaceTimeNotification.java @@ -103,8 +103,6 @@ public void Handle() { .setCategory(NotificationCompat.CATEGORY_CALL) // Set the priority to high since it's a message they should see .setPriority(NotificationCompat.PRIORITY_MAX) - // Sets the intent for when it's clicked - .setContentIntent(openIntent) // Set the content for the notification .setContentTitle(title) .setContentText(body) @@ -114,6 +112,11 @@ public void Handle() { // Set the color. This is the blue primary color .setColor(4888294); + if (callUuid != null) { + // Sets the intent for when it's clicked + notificationBuilder.setContentIntent(openIntent); + } + Log.d(TAG, "Creating notification for FaceTime: " + callUuid); NotificationManagerCompat notificationManagerCompat = NotificationManagerCompat.from(context); diff --git a/assets/changelog/changelog.md b/assets/changelog/changelog.md index a9aaac911..e249b3589 100644 --- a/assets/changelog/changelog.md +++ b/assets/changelog/changelog.md @@ -2,6 +2,20 @@ Below are the last few BlueBubbles App release changelogs +## v1.12.6 + +This is a hotfix update bringing bug fixes to recent issues, + +### Changes + +- Fixes issue with detecting and showing FaceTime notifications. +- Fixes issue where name would appear as "App Killer Manager" on French devices. +- Fixes issue where images would be pixelated when zooming in. +- Removes blurred background for message popups when on High Performance Mode. +- Fixes some issues with Firebase causing app crashes. +- Adds `ngrok-skip-browser-warning` header and custom User-Agent to fix Ngrok Tunnel compatibility issues. +- Fixes FindMy Friends issues for tablets and large-screen devices + ## v1.12.5 This update fixes bugs (especially on Desktop) and brings some of the latest server's features to the client apps. diff --git a/lib/app/layouts/conversation_view/widgets/message/popup/message_popup.dart b/lib/app/layouts/conversation_view/widgets/message/popup/message_popup.dart index bc084ba30..abc5b4be8 100644 --- a/lib/app/layouts/conversation_view/widgets/message/popup/message_popup.dart +++ b/lib/app/layouts/conversation_view/widgets/message/popup/message_popup.dart @@ -448,14 +448,14 @@ class _MessagePopupState extends OptimizedState with SingleTickerP GestureDetector( onTap: popDetails, child: iOS - ? BackdropFilter( + ? (ss.settings.highPerfMode.value ? Container(color: context.theme.colorScheme.background.withOpacity(0.8)) : BackdropFilter( filter: ImageFilter.blur( sigmaX: kIsDesktop && ss.settings.windowEffect.value != WindowEffect.disabled ? 10 : 30, sigmaY: kIsDesktop && ss.settings.windowEffect.value != WindowEffect.disabled ? 10 : 30), child: Container( color: context.theme.colorScheme.properSurface.withOpacity(0.3), ), - ) + )) : null, ), if (iOS) diff --git a/lib/app/layouts/findmy/findmy_page.dart b/lib/app/layouts/findmy/findmy_page.dart index 3eb0eb65e..a58c79961 100644 --- a/lib/app/layouts/findmy/findmy_page.dart +++ b/lib/app/layouts/findmy/findmy_page.dart @@ -26,6 +26,7 @@ import 'package:flutter_map_marker_popup/flutter_map_marker_popup.dart'; import 'package:get/get.dart' hide Response; import 'package:latlong2/latlong.dart'; import 'package:sliding_up_panel2/sliding_up_panel2.dart'; +import 'package:universal_io/io.dart'; class FindMyPage extends StatefulWidget { const FindMyPage({Key? key}) : super(key: key); @@ -120,19 +121,21 @@ class _FindMyPageState extends OptimizedState with SingleTickerProvi anchorPos: AnchorPos.align(AnchorAlign.top), ); } - LocationPermission granted = await Geolocator.checkPermission(); - if (granted == LocationPermission.denied) { - granted = await Geolocator.requestPermission(); - } - if (granted == LocationPermission.whileInUse || granted == LocationPermission.always) { - location = await Geolocator.getCurrentPosition(); - buildLocationMarker(location!); - locationSub = Geolocator.getPositionStream().listen((event) { - setState(() { - buildLocationMarker(event); + if (!(Platform.isLinux && !kIsWeb)) { + LocationPermission granted = await Geolocator.checkPermission(); + if (granted == LocationPermission.denied) { + granted = await Geolocator.requestPermission(); + } + if (granted == LocationPermission.whileInUse || granted == LocationPermission.always) { + location = await Geolocator.getCurrentPosition(); + buildLocationMarker(location!); + locationSub = Geolocator.getPositionStream().listen((event) { + setState(() { + buildLocationMarker(event); + }); }); - }); - mapController.move(LatLng(location!.latitude, location!.longitude), 10); + mapController.move(LatLng(location!.latitude, location!.longitude), 10); + } } setState(() { fetching = false; @@ -690,12 +693,12 @@ class _FindMyPageState extends OptimizedState with SingleTickerProvi if (context.isPhone) { return buildNormal(context, devicesBodySlivers, friendsBodySlivers); } - return buildDesktop(context, devicesBodySlivers, friendsBodySlivers); + return buildTabletLayout(context, devicesBodySlivers, friendsBodySlivers); }, )); } - Widget buildDesktop(BuildContext context, List devicesBodySlivers, List friendsBodySlivers) { + Widget buildTabletLayout(BuildContext context, List devicesBodySlivers, List friendsBodySlivers) { return Obx( () => Scaffold( backgroundColor: context.theme.colorScheme.background.themeOpacity(context), @@ -742,23 +745,24 @@ class _FindMyPageState extends OptimizedState with SingleTickerProvi ), ), ), - SizedBox( - height: appWindow.titleBarHeight, - child: AbsorbPointer( - child: Row(children: [ - Expanded(child: Container()), - ClipRect( - child: BackdropFilter( - filter: ImageFilter.blur(sigmaY: 2, sigmaX: 2), - child: Container( - height: appWindow.titleBarHeight, - width: appWindow.titleBarButtonSize.width * 3, - color: context.theme.colorScheme.properSurface.withOpacity(0.5)), + if (kIsDesktop) + SizedBox( + height: appWindow.titleBarHeight, + child: AbsorbPointer( + child: Row(children: [ + Expanded(child: Container()), + ClipRect( + child: BackdropFilter( + filter: ImageFilter.blur(sigmaY: 2, sigmaX: 2), + child: Container( + height: appWindow.titleBarHeight, + width: appWindow.titleBarButtonSize.width * 3, + color: context.theme.colorScheme.properSurface.withOpacity(0.5)), + ), ), - ), - ]), + ]), + ), ), - ), ], ), ), @@ -1209,6 +1213,7 @@ class _FindMyPageState extends OptimizedState with SingleTickerProvi mapController: mapController, options: MapOptions( zoom: 5.0, + minZoom: 1.0, maxZoom: 18.0, center: location == null ? null : LatLng(location!.latitude, location!.longitude), onTap: (_, __) => popupController.hideAllPopups(), diff --git a/lib/app/layouts/fullscreen_media/fullscreen_image.dart b/lib/app/layouts/fullscreen_media/fullscreen_image.dart index aa3b792bd..0b2af4136 100644 --- a/lib/app/layouts/fullscreen_media/fullscreen_image.dart +++ b/lib/app/layouts/fullscreen_media/fullscreen_image.dart @@ -233,6 +233,7 @@ class _FullscreenImageState extends OptimizedState with Automat errorBuilder: (context, object, stacktrace) => Center( child: Text("Failed to display image", style: context.theme.textTheme.bodyLarge) ), + filterQuality: FilterQuality.high, ), ) : hasError ? Center( child: Text("Failed to load image", style: context.theme.textTheme.bodyLarge) diff --git a/lib/app/layouts/settings/pages/advanced/private_api_panel.dart b/lib/app/layouts/settings/pages/advanced/private_api_panel.dart index 6551fa9d5..9355fbdac 100644 --- a/lib/app/layouts/settings/pages/advanced/private_api_panel.dart +++ b/lib/app/layouts/settings/pages/advanced/private_api_panel.dart @@ -293,15 +293,27 @@ class _PrivateAPIPanelState extends CustomState= 148, - child: SettingsSwitch( - title: "Up Arrow for Quick Edit", - initialVal: ss.settings.editLastSentMessageOnUpArrow.value, - onChanged: (bool val) { - ss.settings.editLastSentMessageOnUpArrow.value = val; - saveSettings(); - }, - subtitle: "Press the Up Arrow to begin editing the last message you sent", - backgroundColor: tileColor, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + color: tileColor, + child: Padding( + padding: const EdgeInsets.only(left: 15.0), + child: SettingsDivider(color: context.theme.colorScheme.surfaceVariant), + ), + ), + SettingsSwitch( + title: "Up Arrow for Quick Edit", + initialVal: ss.settings.editLastSentMessageOnUpArrow.value, + onChanged: (bool val) { + ss.settings.editLastSentMessageOnUpArrow.value = val; + saveSettings(); + }, + subtitle: "Press the Up Arrow to begin editing the last message you sent", + backgroundColor: tileColor, + ), + ], ), ), AnimatedSizeAndFade.showHide( diff --git a/lib/app/layouts/settings/pages/message_view/conversation_panel.dart b/lib/app/layouts/settings/pages/message_view/conversation_panel.dart index 4d70577f2..a1ac60a99 100644 --- a/lib/app/layouts/settings/pages/message_view/conversation_panel.dart +++ b/lib/app/layouts/settings/pages/message_view/conversation_panel.dart @@ -351,6 +351,13 @@ class _ConversationPanelState extends OptimizedState { title: "Send/Receve Sound Volume", subtitle: "Controls the volume of the send and receive sounds", ), + Container( + color: tileColor, + child: Padding( + padding: const EdgeInsets.only(left: 65.0), + child: SettingsDivider(color: context.theme.colorScheme.surfaceVariant), + ), + ), Obx(() => SettingsSlider( startingVal: ss.settings.soundVolume.value.toDouble(), min: 0, diff --git a/lib/app/layouts/settings/pages/server/server_management_panel.dart b/lib/app/layouts/settings/pages/server/server_management_panel.dart index d81f8b468..f62b95cd9 100644 --- a/lib/app/layouts/settings/pages/server/server_management_panel.dart +++ b/lib/app/layouts/settings/pages/server/server_management_panel.dart @@ -715,6 +715,14 @@ class _ServerManagementPanelState extends CustomState ss.settings.localhostPort.value != null ? SettingsSwitch( diff --git a/lib/helpers/types/helpers/file_helpers.dart b/lib/helpers/types/helpers/file_helpers.dart index 69f31c540..33e0799dc 100644 --- a/lib/helpers/types/helpers/file_helpers.dart +++ b/lib/helpers/types/helpers/file_helpers.dart @@ -52,7 +52,7 @@ Future saveImageFromUrl(String guid, String url) async { final filename = getFilenameFromUri(url); try { - final response = await http.dio.get(url, options: Options(responseType: ResponseType.bytes, headers: ss.settings.customHeaders)); + final response = await http.dio.get(url, options: Options(responseType: ResponseType.bytes, headers: http.headers)); Directory baseDir = Directory("${Attachment.baseDirectory}/$guid"); if (!await baseDir.exists()) { diff --git a/lib/services/backend/action_handler.dart b/lib/services/backend/action_handler.dart index 637ae38e4..544da066b 100644 --- a/lib/services/backend/action_handler.dart +++ b/lib/services/backend/action_handler.dart @@ -323,4 +323,21 @@ class ActionHandler extends GetxService { await notif.createIncomingFaceTimeNotification(callUuid, caller, chatIcon, isAudio); } } + + Future handleIncomingFaceTimeCallLegacy(Map data) async { + Logger.info("Handling incoming FaceTime call (legacy)"); + await cs.init(); + String? address = data["caller"]; + String? caller = address; + Uint8List? chatIcon; + + // Find the contact info for the caller + // Load the contact's avatar & name + if (address != null) { + Contact? contact = cs.getContact(address); + chatIcon = contact?.avatar; + caller = contact?.displayName ?? caller; + await notif.createIncomingFaceTimeNotification(null, caller!, chatIcon, false); + } + } } diff --git a/lib/services/backend/java_dart_interop/method_channel_service.dart b/lib/services/backend/java_dart_interop/method_channel_service.dart index 398433895..d1c1d2b23 100644 --- a/lib/services/backend/java_dart_interop/method_channel_service.dart +++ b/lib/services/backend/java_dart_interop/method_channel_service.dart @@ -194,6 +194,12 @@ class MethodChannelService extends GetxService { isRunning = false; } return true; + case "incoming-facetime": + await storeStartup.future; + Logger.info("Received legacy incoming facetime from FCM"); + Map data = jsonDecode(call.arguments.toString().replaceAll('\\"', '<').replaceAll('"', '').replaceAll('<', '"')); + await ActionHandler().handleIncomingFaceTimeCallLegacy(data); + return true; case "ft-call-status-changed": await storeStartup.future; Logger.info("Received facetime call status change from FCM"); diff --git a/lib/services/backend/notifications/notifications_service.dart b/lib/services/backend/notifications/notifications_service.dart index 524d70889..4eaaaea94 100644 --- a/lib/services/backend/notifications/notifications_service.dart +++ b/lib/services/backend/notifications/notifications_service.dart @@ -216,17 +216,19 @@ class NotificationsService extends GetxService { } } - Future createIncomingFaceTimeNotification(String callUuid, String caller, Uint8List? chatIcon, bool isAudio) async { + Future createIncomingFaceTimeNotification(String? callUuid, String caller, Uint8List? chatIcon, bool isAudio) async { // Set some notification defaults String title = caller; - String text = "Answer FaceTime ${isAudio ? 'Audio' : 'Video'} Call"; + String text = "${callUuid == null ? "Incoming" : "Answer"} FaceTime ${isAudio ? 'Audio' : 'Video'} Call"; chatIcon ??= (await loadAsset("assets/images/person64.png")).buffer.asUint8List(); if (kIsWeb && Notification.permission == "granted") { final notif = Notification(title, body: text, icon: "data:image/png;base64,${base64Encode(chatIcon)}", tag: callUuid); - notif.onClick.listen((event) async { - await intents.answerFaceTime(callUuid); - }); + if (callUuid != null) { + notif.onClick.listen((event) async { + await intents.answerFaceTime(callUuid); + }); + } } else if (kIsDesktop) { _lock.synchronized(() async => await showPersistentDesktopFaceTimeNotif(callUuid, caller, chatIcon, isAudio)); } else { @@ -248,7 +250,7 @@ class NotificationsService extends GetxService { } } - Future showPersistentDesktopFaceTimeNotif(String callUuid, String caller, Uint8List? avatar, bool isAudio) async { + Future showPersistentDesktopFaceTimeNotif(String? callUuid, String caller, Uint8List? avatar, bool isAudio) async { List actions = ["Answer", "Ignore"]; List nActions = actions.map((String a) => LocalNotificationAction(text: a)).toList(); LocalNotification? toast; @@ -269,22 +271,24 @@ class NotificationsService extends GetxService { title: caller, body: "Incoming FaceTime ${isAudio ? 'Audio' : 'Video'} Call", duration: LocalNotificationDuration.long, - actions: nActions, + actions: callUuid == null ? null : nActions, ); toast.onClick = () async { await windowManager.show(); }; - toast.onClickAction = (index) async { - if (actions[index] == "Answer") { - await windowManager.show(); - await intents.answerFaceTime(callUuid); - } else { - hideFaceTimeOverlay(callUuid); - await toast?.close(); - } - }; + if (callUuid != null) { + toast.onClickAction = (index) async { + if (actions[index] == "Answer") { + await windowManager.show(); + await intents.answerFaceTime(callUuid); + } else { + hideFaceTimeOverlay(callUuid); + await toast?.close(); + } + }; + } toast.onClose = (reason) async { if (reason == LocalNotificationCloseReason.timedOut && faceTimeOverlays.containsKey(callUuid)) { @@ -292,11 +296,11 @@ class NotificationsService extends GetxService { } }; - if (facetimeNotifications[callUuid] != null) { - await facetimeNotifications[callUuid]?.close(); + if (facetimeNotifications[callUuid ?? caller] != null) { + await facetimeNotifications[callUuid ?? caller]?.close(); } - facetimeNotifications[callUuid] = toast; + facetimeNotifications[callUuid ?? caller] = toast; await toast.show(); } diff --git a/lib/services/network/http_service.dart b/lib/services/network/http_service.dart index 9a1dcc547..5b3fd2bdf 100644 --- a/lib/services/network/http_service.dart +++ b/lib/services/network/http_service.dart @@ -59,6 +59,8 @@ class HttpService extends GetxService { } } + Map get headers => ss.settings.customHeaders..addAll({'ngrok-skip-browser-warning': 'true'}); + /// Initialize dio with a couple options and intercept all requests for logging @override void onInit() { @@ -66,7 +68,7 @@ class HttpService extends GetxService { connectTimeout: const Duration(milliseconds: 15000), receiveTimeout: Duration(milliseconds: ss.settings.apiTimeout.value), sendTimeout: Duration(milliseconds: ss.settings.apiTimeout.value), - headers: ss.settings.customHeaders, + headers: headers, )); dio.interceptors.add(ApiInterceptor()); // Uncomment to run tests on most API requests @@ -251,7 +253,7 @@ class HttpService extends GetxService { final response = await dio.get( "$apiRoot/attachment/$guid/download", queryParameters: buildQueryParams({"original": original}), - options: Options(responseType: ResponseType.bytes, receiveTimeout: dio.options.receiveTimeout! * 12, headers: ss.settings.customHeaders), + options: Options(responseType: ResponseType.bytes, receiveTimeout: dio.options.receiveTimeout! * 12, headers: headers), cancelToken: cancelToken, onReceiveProgress: onReceiveProgress, ); @@ -265,7 +267,7 @@ class HttpService extends GetxService { final response = await dio.get( "$apiRoot/attachment/$guid/live", queryParameters: buildQueryParams(), - options: Options(responseType: ResponseType.bytes, receiveTimeout: dio.options.receiveTimeout! * 12, headers: ss.settings.customHeaders), + options: Options(responseType: ResponseType.bytes, receiveTimeout: dio.options.receiveTimeout! * 12, headers: headers), cancelToken: cancelToken, onReceiveProgress: onReceiveProgress, ); @@ -279,7 +281,7 @@ class HttpService extends GetxService { final response = await dio.get( "$apiRoot/attachment/$guid/blurhash", queryParameters: buildQueryParams(), - options: Options(responseType: ResponseType.bytes, receiveTimeout: dio.options.receiveTimeout! * 12, headers: ss.settings.customHeaders), + options: Options(responseType: ResponseType.bytes, receiveTimeout: dio.options.receiveTimeout! * 12, headers: headers), cancelToken: cancelToken, onReceiveProgress: onReceiveProgress, ); @@ -463,7 +465,7 @@ class HttpService extends GetxService { final response = await dio.get( "$apiRoot/chat/$guid/icon", queryParameters: buildQueryParams(), - options: Options(responseType: ResponseType.bytes, receiveTimeout: dio.options.receiveTimeout! * 12, headers: ss.settings.customHeaders), + options: Options(responseType: ResponseType.bytes, receiveTimeout: dio.options.receiveTimeout! * 12, headers: headers), cancelToken: cancelToken, onReceiveProgress: onReceiveProgress, ); @@ -481,7 +483,7 @@ class HttpService extends GetxService { "$apiRoot/chat/$guid/icon", queryParameters: buildQueryParams(), data: formData, - options: Options(sendTimeout: dio.options.sendTimeout! * 12, receiveTimeout: dio.options.receiveTimeout! * 12, headers: ss.settings.customHeaders), + options: Options(sendTimeout: dio.options.sendTimeout! * 12, receiveTimeout: dio.options.receiveTimeout! * 12, headers: headers), cancelToken: cancelToken, onSendProgress: onSendProgress, ); @@ -570,7 +572,7 @@ class HttpService extends GetxService { final response = await dio.get( "$apiRoot/message/$guid/embedded-media", queryParameters: buildQueryParams(), - options: Options(responseType: ResponseType.bytes, receiveTimeout: dio.options.receiveTimeout! * 12, headers: ss.settings.customHeaders), + options: Options(responseType: ResponseType.bytes, receiveTimeout: dio.options.receiveTimeout! * 12, headers: headers), cancelToken: cancelToken, onReceiveProgress: onReceiveProgress, ); @@ -642,7 +644,7 @@ class HttpService extends GetxService { cancelToken: cancelToken, data: formData, onSendProgress: onSendProgress, - options: Options(sendTimeout: dio.options.sendTimeout! * 12, receiveTimeout: dio.options.receiveTimeout! * 12, headers: ss.settings.customHeaders), + options: Options(sendTimeout: dio.options.sendTimeout! * 12, receiveTimeout: dio.options.receiveTimeout! * 12, headers: headers), ); return returnSuccessOrError(response); }); @@ -852,7 +854,7 @@ class HttpService extends GetxService { queryParameters: buildQueryParams(), data: contacts, onSendProgress: onSendProgress, - options: Options(sendTimeout: dio.options.sendTimeout! * 12, receiveTimeout: dio.options.receiveTimeout! * 12, headers: ss.settings.customHeaders), + options: Options(sendTimeout: dio.options.sendTimeout! * 12, receiveTimeout: dio.options.receiveTimeout! * 12, headers: headers), cancelToken: cancelToken ); return returnSuccessOrError(response); @@ -1061,7 +1063,7 @@ class HttpService extends GetxService { "$apiRoot/icloud/findmy/devices/refresh", queryParameters: buildQueryParams(), cancelToken: cancelToken, - options: Options(receiveTimeout: dio.options.receiveTimeout! * 12, headers: ss.settings.customHeaders), + options: Options(receiveTimeout: dio.options.receiveTimeout! * 12, headers: headers), ); return returnSuccessOrError(response); }); @@ -1083,7 +1085,7 @@ class HttpService extends GetxService { return runApiGuarded(() async { final response = await dio.get( url, - options: Options(responseType: ResponseType.bytes, receiveTimeout: dio.options.receiveTimeout! * 12, headers: ss.settings.customHeaders), + options: Options(responseType: ResponseType.bytes, receiveTimeout: dio.options.receiveTimeout! * 12, headers: headers), cancelToken: cancelToken, onReceiveProgress: progress, ); diff --git a/lib/services/network/socket_service.dart b/lib/services/network/socket_service.dart index 392abf543..1ca1a6224 100644 --- a/lib/services/network/socket_service.dart +++ b/lib/services/network/socket_service.dart @@ -53,7 +53,7 @@ class SocketService extends GetxService { OptionBuilder options = OptionBuilder() .setQuery({"guid": password}) .setTransports(['websocket', 'polling']) - .setExtraHeaders(ss.settings.customHeaders) + .setExtraHeaders(http.headers) // Disable so that we can create the listeners first .disableAutoConnect() .enableReconnection(); @@ -81,6 +81,7 @@ class SocketService extends GetxService { socket.on("participant-removed", (data) => handleCustomEvent("participant-removed", data)); socket.on("participant-added", (data) => handleCustomEvent("participant-added", data)); socket.on("participant-left", (data) => handleCustomEvent("participant-left", data)); + socket.on("incoming-facetime", (data) => handleCustomEvent("incoming-facetime", jsonDecode(data))); socket.on("ft-call-status-changed", (data) => handleCustomEvent("ft-call-status-changed", data)); socket.on("answer-facetime", (data) => handleCustomEvent("answer-facetime", data)); } @@ -238,6 +239,10 @@ class SocketService extends GetxService { controller.showTypingIndicator.value = data["display"]; } return; + case "incoming-facetime": + Logger.info("Received legacy incoming FaceTime call"); + await ActionHandler().handleIncomingFaceTimeCallLegacy(data); + return; case "ft-call-status-changed": Logger.info("Received FaceTime call status change"); await ActionHandler().handleFaceTimeStatusChange(data); diff --git a/pubspec.yaml b/pubspec.yaml index a844ed1b0..0697a760f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -12,7 +12,7 @@ description: Send iMessages on Android using BlueBubbles! # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.12.5+59 +version: 1.12.6+60 publish_to: none environment: