From 2797974d45e49a8465d6324b7f52b7d4f5fd93ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Ku=C3=9Fowski?= Date: Sun, 27 Jul 2025 07:44:48 +0200 Subject: [PATCH 1/2] fix: Use retry http client --- lib/utils/client_manager.dart | 3 +-- lib/utils/custom_http_client.dart | 12 +++++++++++- lib/utils/error_reporter.dart | 13 ++++++++++++- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/lib/utils/client_manager.dart b/lib/utils/client_manager.dart index ddda56824..5c5a07663 100644 --- a/lib/utils/client_manager.dart +++ b/lib/utils/client_manager.dart @@ -106,8 +106,7 @@ abstract class ClientManager { return Client( clientName, - httpClient: - PlatformInfos.isAndroid ? CustomHttpClient.createHTTPClient() : null, + httpClient: CustomHttpClient.createHTTPClient(), verificationMethods: { KeyVerificationMethod.numbers, if (kIsWeb || PlatformInfos.isMobile || PlatformInfos.isLinux) diff --git a/lib/utils/custom_http_client.dart b/lib/utils/custom_http_client.dart index 479e5edb5..b0a3dcb28 100644 --- a/lib/utils/custom_http_client.dart +++ b/lib/utils/custom_http_client.dart @@ -3,9 +3,15 @@ import 'dart:io'; import 'package:http/http.dart' as http; import 'package:http/io_client.dart'; +import 'package:http/retry.dart' as retry; import 'package:fluffychat/config/isrg_x1.dart'; +import 'package:fluffychat/utils/platform_infos.dart'; +/// Custom Client to add an additional certificate. This is for the isrg X1 +/// certificate which is needed for LetsEncrypt certificates. It is shipped +/// on Android since OS version 7.1. As long as we support older versions we +/// still have to ship this certificate by ourself. class CustomHttpClient { static HttpClient customHttpClient(String? cert) { final context = SecurityContext.defaultContext; @@ -26,5 +32,9 @@ class CustomHttpClient { return HttpClient(context: context); } - static http.Client createHTTPClient() => IOClient(customHttpClient(ISRG_X1)); + static http.Client createHTTPClient() => retry.RetryClient( + PlatformInfos.isAndroid + ? IOClient(customHttpClient(ISRG_X1)) + : http.Client(), + ); } diff --git a/lib/utils/error_reporter.dart b/lib/utils/error_reporter.dart index e68f5cdea..6a8b0f866 100644 --- a/lib/utils/error_reporter.dart +++ b/lib/utils/error_reporter.dart @@ -5,6 +5,7 @@ import 'package:flutter/services.dart'; import 'package:flutter_highlighter/flutter_highlighter.dart'; import 'package:flutter_highlighter/themes/shades-of-purple.dart'; +import 'package:http/http.dart' as http; import 'package:matrix/matrix.dart'; import 'package:path/path.dart' as path; import 'package:path_provider/path_provider.dart'; @@ -20,6 +21,14 @@ class ErrorReporter { const ErrorReporter(this.context, [this.message]); + static const Set ingoredTypes = { + IOException, + http.ClientException, + SocketException, + TlsException, + HandshakeException, + }; + Future _getTemporaryErrorLogFile() async { final tempDir = await getTemporaryDirectory(); return File(path.join(tempDir.path, 'error_log.txt')); @@ -29,6 +38,7 @@ class ErrorReporter { Object error, [ StackTrace? stackTrace, ]) async { + if (ingoredTypes.contains(error.runtimeType)) return; final file = await _getTemporaryErrorLogFile(); if (await file.exists()) await file.delete(); await file.writeAsString( @@ -40,11 +50,12 @@ class ErrorReporter { final file = await _getTemporaryErrorLogFile(); if (!(await file.exists())) return; final content = await file.readAsString(); - _onErrorCallback(content); + await file.delete(); } void onErrorCallback(Object error, [StackTrace? stackTrace]) { + if (ingoredTypes.contains(error.runtimeType)) return; Logs().e(message ?? 'Error caught', error, stackTrace); final text = '$error\n${stackTrace ?? ''}'; return _onErrorCallback(text); From 029eae7979139573ec1a9814d9c1f7005f2f8d66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Ku=C3=9Fowski?= Date: Sun, 27 Jul 2025 11:30:24 +0200 Subject: [PATCH 2/2] fix: Open external account management when trying to delete devices --- lib/pages/device_settings/device_settings.dart | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/lib/pages/device_settings/device_settings.dart b/lib/pages/device_settings/device_settings.dart index a23545f0b..2114e999c 100644 --- a/lib/pages/device_settings/device_settings.dart +++ b/lib/pages/device_settings/device_settings.dart @@ -3,6 +3,7 @@ import 'package:flutter/material.dart'; import 'package:collection/collection.dart' show IterableExtension; import 'package:matrix/encryption/utils/key_verification.dart'; import 'package:matrix/matrix.dart'; +import 'package:url_launcher/url_launcher_string.dart'; import 'package:fluffychat/l10n/l10n.dart'; import 'package:fluffychat/pages/device_settings/device_settings_view.dart'; @@ -52,6 +53,18 @@ class DevicesSettingsController extends State { } void removeDevicesAction(List devices) async { + final client = Matrix.of(context).client; + + final accountManageUrl = client.wellKnown?.additionalProperties + .tryGetMap('org.matrix.msc2965.authentication') + ?.tryGet('account'); + if (accountManageUrl != null) { + launchUrlString( + accountManageUrl, + mode: LaunchMode.inAppBrowserView, + ); + return; + } if (await showOkCancelAlertDialog( context: context, title: L10n.of(context).areYouSure,