From e8ee58d6d9c3287912b7853dbf7834eb8160358d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Ku=C3=9Fowski?= Date: Tue, 10 Mar 2026 09:06:03 +0100 Subject: [PATCH 1/6] refactor: Disable custom image resizer for macOS and windows --- lib/utils/client_manager.dart | 4 +++- lib/utils/platform_infos.dart | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/utils/client_manager.dart b/lib/utils/client_manager.dart index 856a907ab..ffb687926 100644 --- a/lib/utils/client_manager.dart +++ b/lib/utils/client_manager.dart @@ -123,7 +123,9 @@ abstract class ClientManager { // To make room emotes work 'im.ponies.room_emotes', }, - customImageResizer: customImageResizer, + customImageResizer: PlatformInfos.supportsCustomImageResizer + ? customImageResizer + : null, logLevel: kReleaseMode ? Level.warning : Level.verbose, database: await flutterMatrixSdkDatabaseBuilder(clientName), supportedLoginTypes: { diff --git a/lib/utils/platform_infos.dart b/lib/utils/platform_infos.dart index 0f225b733..1c1b26236 100644 --- a/lib/utils/platform_infos.dart +++ b/lib/utils/platform_infos.dart @@ -33,6 +33,9 @@ abstract class PlatformInfos { static bool get supportsVideoPlayer => !PlatformInfos.isWindows && !PlatformInfos.isLinux; + static bool get supportsCustomImageResizer => + PlatformInfos.isWeb || PlatformInfos.isMobile; + /// Web could also record in theory but currently only wav which is too large static bool get platformCanRecord => (isMobile || isMacOS || isWeb); From c90fdc3e7536d2c42f107cc229bd42bd6a52de04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Ku=C3=9Fowski?= Date: Tue, 10 Mar 2026 09:13:57 +0100 Subject: [PATCH 2/6] chore: make sendTimelineEventTimeout configurable --- lib/config/setting_keys.dart | 3 ++- lib/utils/client_manager.dart | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/config/setting_keys.dart b/lib/config/setting_keys.dart index 627313ed7..471f88978 100644 --- a/lib/config/setting_keys.dart +++ b/lib/config/setting_keys.dart @@ -65,7 +65,8 @@ enum AppSettings { 'chat.fluffy.privacy_policy_url', 'https://fluffychat.im/en/privacy', ), - tos('chat.fluffy.tos_url', 'https://fluffychat.im/en/tos'); + tos('chat.fluffy.tos_url', 'https://fluffychat.im/en/tos'), + sendTimelineEventTimeout('chat.fluffy.send_timeline_event_timeout', 15); final String key; final T defaultValue; diff --git a/lib/utils/client_manager.dart b/lib/utils/client_manager.dart index ffb687926..bdb33f954 100644 --- a/lib/utils/client_manager.dart +++ b/lib/utils/client_manager.dart @@ -143,6 +143,9 @@ abstract class ClientManager { onSoftLogout: enableSoftLogout ? (client) => client.refreshAccessToken() : null, + sendTimelineEventTimeout: Duration( + seconds: AppSettings.sendTimelineEventTimeout.value, + ), ); } From a490a40379c28e0613d140117cfb06b390809557 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Ku=C3=9Fowski?= Date: Tue, 10 Mar 2026 09:29:45 +0100 Subject: [PATCH 3/6] chore: Adjust design --- lib/config/themes.dart | 2 +- .../invitation_selection/invitation_selection_view.dart | 5 ++--- lib/widgets/adaptive_dialogs/adaptive_dialog_action.dart | 4 +++- lib/widgets/adaptive_dialogs/public_room_dialog.dart | 1 + lib/widgets/permission_slider_dialog.dart | 2 +- lib/widgets/qr_code_viewer.dart | 6 +++++- 6 files changed, 13 insertions(+), 7 deletions(-) diff --git a/lib/config/themes.dart b/lib/config/themes.dart index 122eef918..42d83dc9e 100644 --- a/lib/config/themes.dart +++ b/lib/config/themes.dart @@ -74,7 +74,7 @@ abstract class FluffyThemes { ), inputDecorationTheme: InputDecorationTheme( border: OutlineInputBorder( - borderRadius: BorderRadius.circular(AppConfig.borderRadius), + borderRadius: BorderRadius.circular(AppConfig.borderRadius / 2), ), contentPadding: const EdgeInsets.all(12), ), diff --git a/lib/pages/invitation_selection/invitation_selection_view.dart b/lib/pages/invitation_selection/invitation_selection_view.dart index 4db33841f..562713d80 100644 --- a/lib/pages/invitation_selection/invitation_selection_view.dart +++ b/lib/pages/invitation_selection/invitation_selection_view.dart @@ -191,10 +191,9 @@ class _InviteContactListTile extends StatelessWidget { overflow: TextOverflow.ellipsis, style: TextStyle(color: theme.colorScheme.secondary), ), - trailing: TextButton.icon( + trailing: TextButton( onPressed: isMember ? null : onTap, - label: Text(isMember ? l10n.participant : l10n.invite), - icon: Icon(isMember ? Icons.check : Icons.add), + child: Text(isMember ? l10n.participant : l10n.invite), ), ); } diff --git a/lib/widgets/adaptive_dialogs/adaptive_dialog_action.dart b/lib/widgets/adaptive_dialogs/adaptive_dialog_action.dart index 09e8d6ac6..6fbc9a0cd 100644 --- a/lib/widgets/adaptive_dialogs/adaptive_dialog_action.dart +++ b/lib/widgets/adaptive_dialogs/adaptive_dialog_action.dart @@ -108,7 +108,9 @@ class AdaptiveDialogInkWell extends StatelessWidget { ); } return Material( - color: theme.colorScheme.surfaceBright, + color: onTap == null + ? theme.colorScheme.surfaceContainer + : theme.colorScheme.surfaceBright, borderRadius: BorderRadius.circular(AppConfig.borderRadius / 2), child: InkWell( borderRadius: BorderRadius.circular(AppConfig.borderRadius / 2), diff --git a/lib/widgets/adaptive_dialogs/public_room_dialog.dart b/lib/widgets/adaptive_dialogs/public_room_dialog.dart index 975507564..bafa58643 100644 --- a/lib/widgets/adaptive_dialogs/public_room_dialog.dart +++ b/lib/widgets/adaptive_dialogs/public_room_dialog.dart @@ -185,6 +185,7 @@ class PublicRoomDialog extends StatelessWidget { style: theme.textTheme.bodyMedium ?.copyWith(fontSize: 10), ), + maxLines: 1, textAlign: TextAlign.center, ), ), diff --git a/lib/widgets/permission_slider_dialog.dart b/lib/widgets/permission_slider_dialog.dart index 1a0f2556d..63cd0897d 100644 --- a/lib/widgets/permission_slider_dialog.dart +++ b/lib/widgets/permission_slider_dialog.dart @@ -20,7 +20,7 @@ Future showPermissionChooser( child: Column( mainAxisSize: .min, crossAxisAlignment: .stretch, - spacing: 12.0, + spacing: 16.0, children: [ Text(L10n.of(context).setPowerLevelDescription), ValueListenableBuilder( diff --git a/lib/widgets/qr_code_viewer.dart b/lib/widgets/qr_code_viewer.dart index ac87d9942..83c44e741 100644 --- a/lib/widgets/qr_code_viewer.dart +++ b/lib/widgets/qr_code_viewer.dart @@ -91,7 +91,11 @@ class QrCodeViewer extends StatelessWidget { margin: const EdgeInsets.all(32.0), padding: const EdgeInsets.all(32.0), decoration: BoxDecoration( - color: theme.colorScheme.primaryContainer, + border: Border.all( + color: theme.colorScheme.onPrimaryContainer, + width: 4, + ), + color: theme.colorScheme.surfaceBright, borderRadius: BorderRadius.circular(AppConfig.borderRadius), ), child: Column( From cd99f6a460632b68eb42c6e420ff04802547460e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Ku=C3=9Fowski?= Date: Tue, 10 Mar 2026 09:38:13 +0100 Subject: [PATCH 4/6] chore: Remove converser from recommended homeservers as it doesn't have open registration --- recommended_homeservers.json | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/recommended_homeservers.json b/recommended_homeservers.json index ec2f3dc75..fe785234f 100644 --- a/recommended_homeservers.json +++ b/recommended_homeservers.json @@ -10,16 +10,6 @@ "English" ] }, - { - "name": "converser.eu", - "website": "https://converser.eu", - "description": "A free and decentralized communication server.", - "reg_method": "oidc", - "languages": [ - "All", - "Français" - ] - }, { "name": "mozilla.org", "website": "https://mozilla.org", @@ -29,15 +19,6 @@ "All", "English" ] - }, - { - "name": "magdeburg.jetzt", - "website": "https://magdeburg.jetzt", - "reg_method": "oidc", - "languages": [ - "All", - "Deutsch" - ] } ] } \ No newline at end of file From 210ebdae6e19b0e40b68a823a50dda93e6919025 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Ku=C3=9Fowski?= Date: Tue, 10 Mar 2026 09:45:07 +0100 Subject: [PATCH 5/6] chore: Added deeplinks to test protocol --- .github/ISSUE_TEMPLATE/test_report.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/test_report.md b/.github/ISSUE_TEMPLATE/test_report.md index 9a7ed7028..fb97739be 100644 --- a/.github/ISSUE_TEMPLATE/test_report.md +++ b/.github/ISSUE_TEMPLATE/test_report.md @@ -39,3 +39,6 @@ labels: test 10. Drag&Drop to send a file into a chat still works: - [ ] Web - [ ] Linux +11. Deeplinks are still working? https://matrix.to/#/@krille:janian.de + - [ ] Android + - [ ] iOS \ No newline at end of file From a7c89418ebc8513a5889a828ca468660c479ef2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Ku=C3=9Fowski?= Date: Tue, 10 Mar 2026 10:04:08 +0100 Subject: [PATCH 6/6] chore: Implement pick SSO provider from dialog and add tchncs.de --- lib/utils/sign_in_flows/check_homeserver.dart | 2 +- lib/utils/sign_in_flows/sso_login.dart | 34 ++++++++++++++++++- recommended_homeservers.json | 11 ++++++ 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/lib/utils/sign_in_flows/check_homeserver.dart b/lib/utils/sign_in_flows/check_homeserver.dart index 85f7a3712..ed3e61c92 100644 --- a/lib/utils/sign_in_flows/check_homeserver.dart +++ b/lib/utils/sign_in_flows/check_homeserver.dart @@ -52,7 +52,7 @@ Future connectToHomeserverFlow( if (authMetadata != null && AppSettings.enableMatrixNativeOIDC.value) { await oidcLoginFlow(client, context, signUp); } else if (supportsSso) { - await ssoLoginFlow(client, context, signUp); + await ssoLoginFlow(client, context, signUp, loginFlows); } else { if (signUp && regLink != null) { await launchUrlString(regLink); diff --git a/lib/utils/sign_in_flows/sso_login.dart b/lib/utils/sign_in_flows/sso_login.dart index 1721a2ead..7f7a924d4 100644 --- a/lib/utils/sign_in_flows/sso_login.dart +++ b/lib/utils/sign_in_flows/sso_login.dart @@ -3,20 +3,52 @@ import 'package:flutter/material.dart'; import 'package:flutter_web_auth_2/flutter_web_auth_2.dart'; import 'package:matrix/matrix.dart'; +import 'package:fluffychat/l10n/l10n.dart'; import 'package:fluffychat/utils/platform_infos.dart'; import 'package:fluffychat/utils/sign_in_flows/calc_redirect_url.dart'; +import 'package:fluffychat/widgets/adaptive_dialogs/show_modal_action_popup.dart'; Future ssoLoginFlow( Client client, BuildContext context, bool signUp, + List loginFlows, ) async { final (redirectUrl, urlScheme) = calcRedirectUrl(withAuthHtmlPath: true); Logs().i('Starting legacy SSO Flow with redirect URL', redirectUrl); + final ssoProviders = + (loginFlows + .firstWhere((flow) => flow.type == 'm.login.sso') + .additionalProperties['identity_providers'] + as List?) + ?.map( + (json) => ( + name: json['name'] as String, + id: json['id'] as String, + brand: json['brand'] as String?, + icon: json['icon'] as String?, + ), + ) + .toList(); + + final provider = ssoProviders == null + ? null + : await showModalActionPopup( + context: context, + title: L10n.of(context).logInTo(client.homeserver!.host), + actions: ssoProviders + .map( + (provider) => + AdaptiveModalAction(label: provider.name, value: provider), + ) + .toList(), + ); + final url = client.homeserver!.replace( - path: '/_matrix/client/v3/login/sso/redirect', + path: + '/_matrix/client/v3/login/sso/redirect${provider == null ? '' : '/${provider.id}'}', queryParameters: { 'redirectUrl': redirectUrl.toString(), 'action': signUp ? 'register' : 'login', diff --git a/recommended_homeservers.json b/recommended_homeservers.json index fe785234f..fef601847 100644 --- a/recommended_homeservers.json +++ b/recommended_homeservers.json @@ -19,6 +19,17 @@ "All", "English" ] + }, + { + "name": "tchncs.de", + "website": "https://tchncs.de", + "description": "A general homeserver. Owner also hosts other FOSS services.", + "reg_method": "oidc", + "languages": [ + "All", + "English", + "Deutsch" + ] } ] } \ No newline at end of file