diff --git a/.github/workflows/matrix_notify.yaml b/.github/workflows/matrix_notify.yaml
index fe4672808..f1583f11a 100644
--- a/.github/workflows/matrix_notify.yaml
+++ b/.github/workflows/matrix_notify.yaml
@@ -8,6 +8,7 @@ on:
jobs:
notify:
+ if: ${{ (github.event_name == 'issues' && github.event.issue.user.login != 'krille-chan') || (github.event_name == 'pull_request_target' && github.event.pull_request.user.login != 'krille-chan') }}
runs-on: ubuntu-latest
steps:
- name: Send notification to Matrix room
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index 5161a4d83..1b3f5182c 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -106,7 +106,7 @@
-
+
diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist
index e828d1713..51765d1c9 100644
--- a/ios/Runner/Info.plist
+++ b/ios/Runner/Info.plist
@@ -35,7 +35,6 @@
ShareMedia-$(PRODUCT_BUNDLE_IDENTIFIER)
im.fluffychat
- chat.fluffy
matrix
diff --git a/lib/config/app_config.dart b/lib/config/app_config.dart
index d865b6eee..0dcb6c4c0 100644
--- a/lib/config/app_config.dart
+++ b/lib/config/app_config.dart
@@ -22,15 +22,15 @@ abstract class AppConfig {
static const double columnWidth = 360.0;
static const String enablePushTutorial =
- 'https://fluffy.chat/faq/#push_without_google_services';
+ 'https://fluffychat.im/faq/#push_without_google_services';
static const String encryptionTutorial =
- 'https://fluffy.chat/faq/#how_to_use_end_to_end_encryption';
+ 'https://fluffychat.im/faq/#how_to_use_end_to_end_encryption';
static const String startChatTutorial =
- 'https://fluffy.chat/faq/#how_do_i_find_other_users';
+ 'https://fluffychat.im/faq/#how_do_i_find_other_users';
static const String howDoIGetStickersTutorial =
- 'https://fluffy.chat/faq/#how_do_i_get_stickers';
+ 'https://fluffychat.im/faq/#how_do_i_get_stickers';
static const String appId = 'im.fluffychat.FluffyChat';
- static const String appOpenUrlScheme = 'chat.fluffy';
+ static const String appOpenUrlScheme = 'im.fluffychat';
static const String sourceCodeUrl =
'https://github.com/krille-chan/fluffychat';
diff --git a/lib/config/routes.dart b/lib/config/routes.dart
index a6d2d70ce..6ae9d3b67 100644
--- a/lib/config/routes.dart
+++ b/lib/config/routes.dart
@@ -170,8 +170,14 @@ abstract class AppRoutes {
),
GoRoute(
path: 'newprivatechat',
- pageBuilder: (context, state) =>
- defaultPageBuilder(context, state, const NewPrivateChat()),
+ pageBuilder: (context, state) => defaultPageBuilder(
+ context,
+ state,
+ NewPrivateChat(
+ key: ValueKey('new_chat_${state.uri.query}'),
+ deeplink: state.uri.queryParameters['deeplink'],
+ ),
+ ),
redirect: loggedOutRedirect,
),
GoRoute(
diff --git a/lib/config/setting_keys.dart b/lib/config/setting_keys.dart
index c623ce6c7..627313ed7 100644
--- a/lib/config/setting_keys.dart
+++ b/lib/config/setting_keys.dart
@@ -56,16 +56,16 @@ enum AppSettings {
enableMatrixNativeOIDC('chat.fluffy.enable_matrix_native_oidc', false),
presetHomeserver('chat.fluffy.preset_homeserver', ''),
welcomeText('chat.fluffy.welcome_text', ''),
- website('chat.fluffy.website_url', 'https://fluffy.chat'),
+ website('chat.fluffy.website_url', 'https://fluffychat.im'),
logoUrl(
'chat.fluffy.logo_url',
- 'https://fluffy.chat/assets/favicon.png',
+ 'https://fluffychat.im/assets/favicon.png',
),
privacyPolicy(
'chat.fluffy.privacy_policy_url',
- 'https://fluffy.chat/en/privacy',
+ 'https://fluffychat.im/en/privacy',
),
- tos('chat.fluffy.tos_url', 'https://fluffy.chat/en/tos');
+ tos('chat.fluffy.tos_url', 'https://fluffychat.im/en/tos');
final String key;
final T defaultValue;
diff --git a/lib/pages/chat/events/audio_player.dart b/lib/pages/chat/events/audio_player.dart
index f2edc232f..f78345d37 100644
--- a/lib/pages/chat/events/audio_player.dart
+++ b/lib/pages/chat/events/audio_player.dart
@@ -165,11 +165,11 @@ class AudioPlayerState extends State {
: null,
);
- if (!kIsWeb) {
+ final attachmentUrl = widget.event.attachmentOrThumbnailMxcUrl();
+
+ if (!kIsWeb && attachmentUrl != null) {
final tempDir = await getTemporaryDirectory();
- final fileName = Uri.encodeComponent(
- widget.event.attachmentOrThumbnailMxcUrl()!.pathSegments.last,
- );
+ final fileName = Uri.encodeComponent(attachmentUrl.pathSegments.last);
file = File('${tempDir.path}/${fileName}_${matrixFile.name}');
await file.writeAsBytes(matrixFile.bytes);
diff --git a/lib/pages/chat/send_file_dialog.dart b/lib/pages/chat/send_file_dialog.dart
index 57f124b2c..4e67b338d 100644
--- a/lib/pages/chat/send_file_dialog.dart
+++ b/lib/pages/chat/send_file_dialog.dart
@@ -1,8 +1,9 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
+import 'package:async/async.dart' show Result;
import 'package:cross_file/cross_file.dart';
-import 'package:matrix/matrix.dart';
+import 'package:matrix/matrix.dart' hide Result;
import 'package:mime/mime.dart';
import 'package:fluffychat/config/app_config.dart';
@@ -53,8 +54,9 @@ class SendFileDialogState extends State {
}
scaffoldMessenger.showLoadingSnackBar(l10n.prepareSendingAttachment);
Navigator.of(context, rootNavigator: false).pop();
- final clientConfig = await widget.room.client.getConfig();
- final maxUploadSize = clientConfig.mUploadSize ?? 100 * 1000 * 1000;
+ final clientConfig = await Result.capture(widget.room.client.getConfig());
+ final maxUploadSize =
+ clientConfig.asValue?.value.mUploadSize ?? 100 * 1000 * 1000;
for (final xfile in widget.files) {
final MatrixFile file;
diff --git a/lib/pages/chat_list/chat_list.dart b/lib/pages/chat_list/chat_list.dart
index d8751f9cb..75181bf04 100644
--- a/lib/pages/chat_list/chat_list.dart
+++ b/lib/pages/chat_list/chat_list.dart
@@ -1,9 +1,9 @@
import 'dart:async';
+import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
-import 'package:app_links/app_links.dart';
import 'package:cross_file/cross_file.dart';
import 'package:flutter_shortcuts_new/flutter_shortcuts_new.dart';
import 'package:go_router/go_router.dart';
@@ -11,6 +11,7 @@ import 'package:matrix/matrix.dart' as sdk;
import 'package:matrix/matrix.dart';
import 'package:receive_sharing_intent/receive_sharing_intent.dart';
+import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pages/chat_list/chat_list_view.dart';
import 'package:fluffychat/utils/localized_exception_extension.dart';
@@ -71,8 +72,6 @@ class ChatListController extends State
StreamSubscription? _intentFileStreamSubscription;
- StreamSubscription? _intentUriStreamSubscription;
-
late ActiveFilter activeFilter;
String? _activeSpaceId;
@@ -308,6 +307,12 @@ class ChatListController extends State
void _processIncomingSharedMedia(List files) {
if (files.isEmpty) return;
+ if (files.singleOrNull?.path.startsWith(AppConfig.deepLinkPrefix) == true) {
+ return;
+ }
+
+ inspect(files);
+
showScaffoldDialog(
context: context,
builder: (context) => ShareScaffoldDialog(
@@ -326,14 +331,6 @@ class ChatListController extends State
);
}
- Future _processIncomingUris(Uri? uri) async {
- if (uri == null) return;
- context.go('/rooms');
- WidgetsBinding.instance.addPostFrameCallback((_) {
- UrlLauncher(context, uri.toString()).openMatrixToUrl();
- });
- }
-
void _initReceiveSharingIntent() {
if (!PlatformInfos.isMobile) return;
@@ -347,11 +344,6 @@ class ChatListController extends State
_processIncomingSharedMedia,
);
- // For receiving shared Uris
- _intentUriStreamSubscription = AppLinks().uriLinkStream.listen(
- _processIncomingUris,
- );
-
if (PlatformInfos.isAndroid) {
final shortcuts = FlutterShortcuts();
shortcuts.initialize().then(
@@ -394,7 +386,6 @@ class ChatListController extends State
void dispose() {
_intentDataStreamSubscription?.cancel();
_intentFileStreamSubscription?.cancel();
- _intentUriStreamSubscription?.cancel();
scrollController.removeListener(_onScroll);
super.dispose();
}
diff --git a/lib/pages/new_private_chat/new_private_chat.dart b/lib/pages/new_private_chat/new_private_chat.dart
index 55435cc11..e5d8e202f 100644
--- a/lib/pages/new_private_chat/new_private_chat.dart
+++ b/lib/pages/new_private_chat/new_private_chat.dart
@@ -17,7 +17,8 @@ import 'package:fluffychat/widgets/matrix.dart';
import '../../widgets/adaptive_dialogs/user_dialog.dart';
class NewPrivateChat extends StatefulWidget {
- const NewPrivateChat({super.key});
+ final String? deeplink;
+ const NewPrivateChat({super.key, required this.deeplink});
@override
NewPrivateChatController createState() => NewPrivateChatController();
@@ -33,6 +34,18 @@ class NewPrivateChatController extends State {
static const Duration _coolDown = Duration(milliseconds: 500);
+ @override
+ void initState() {
+ super.initState();
+
+ final deeplink = widget.deeplink;
+ if (deeplink != null) {
+ WidgetsBinding.instance.addPostFrameCallback((_) {
+ UrlLauncher(context, deeplink).openMatrixToUrl();
+ });
+ }
+ }
+
Future searchUsers([String? input]) async {
final searchTerm = input ?? controller.text;
if (searchTerm.isEmpty) {
diff --git a/lib/widgets/adaptive_dialogs/adaptive_dialog_action.dart b/lib/widgets/adaptive_dialogs/adaptive_dialog_action.dart
index 5848cf545..09e8d6ac6 100644
--- a/lib/widgets/adaptive_dialogs/adaptive_dialog_action.dart
+++ b/lib/widgets/adaptive_dialogs/adaptive_dialog_action.dart
@@ -85,7 +85,7 @@ class AdaptiveDialogAction extends StatelessWidget {
class AdaptiveDialogInkWell extends StatelessWidget {
final Widget child;
- final VoidCallback onTap;
+ final VoidCallback? onTap;
final EdgeInsets padding;
const AdaptiveDialogInkWell({
@@ -125,7 +125,7 @@ class AdaptiveDialogInkWell extends StatelessWidget {
class AdaptiveIconTextButton extends StatelessWidget {
final String label;
final IconData icon;
- final VoidCallback onTap;
+ final VoidCallback? onTap;
const AdaptiveIconTextButton({
super.key,
required this.label,
diff --git a/lib/widgets/adaptive_dialogs/user_dialog.dart b/lib/widgets/adaptive_dialogs/user_dialog.dart
index 4be6ba9d6..674bd9c1f 100644
--- a/lib/widgets/adaptive_dialogs/user_dialog.dart
+++ b/lib/widgets/adaptive_dialogs/user_dialog.dart
@@ -195,35 +195,39 @@ class UserDialog extends StatelessWidget {
AdaptiveIconTextButton(
label: L10n.of(context).block,
icon: Icons.block_outlined,
- onTap: () {
- final router = GoRouter.of(context);
- Navigator.of(context).pop();
- router.go(
- '/rooms/settings/security/ignorelist',
- extra: profile.userId,
- );
- },
+ onTap: client.userID == profile.userId
+ ? null
+ : () {
+ final router = GoRouter.of(context);
+ Navigator.of(context).pop();
+ router.go(
+ '/rooms/settings/security/ignorelist',
+ extra: profile.userId,
+ );
+ },
),
AdaptiveIconTextButton(
label: L10n.of(context).report,
icon: Icons.gavel_outlined,
- onTap: () async {
- Navigator.of(context).pop();
- final reason = await showTextInputDialog(
- context: context,
- title: L10n.of(context).whyDoYouWantToReportThis,
- okLabel: L10n.of(context).report,
- cancelLabel: L10n.of(context).cancel,
- hintText: L10n.of(context).reason,
- );
- if (reason == null || reason.isEmpty) return;
- await showFutureLoadingDialog(
- context: context,
- future: () => Matrix.of(
- context,
- ).client.reportUser(profile.userId, reason),
- );
- },
+ onTap: client.userID == profile.userId
+ ? null
+ : () async {
+ Navigator.of(context).pop();
+ final reason = await showTextInputDialog(
+ context: context,
+ title: L10n.of(context).whyDoYouWantToReportThis,
+ okLabel: L10n.of(context).report,
+ cancelLabel: L10n.of(context).cancel,
+ hintText: L10n.of(context).reason,
+ );
+ if (reason == null || reason.isEmpty) return;
+ await showFutureLoadingDialog(
+ context: context,
+ future: () => Matrix.of(
+ context,
+ ).client.reportUser(profile.userId, reason),
+ );
+ },
),
AdaptiveIconTextButton(
label: L10n.of(context).share,
@@ -236,17 +240,19 @@ class UserDialog extends StatelessWidget {
],
),
AdaptiveDialogInkWell(
- onTap: () async {
- final router = GoRouter.of(context);
- final roomIdResult = await showFutureLoadingDialog(
- context: context,
- future: () => client.startDirectChat(profile.userId),
- );
- final roomId = roomIdResult.result;
- if (roomId == null) return;
- if (context.mounted) Navigator.of(context).pop();
- router.go('/rooms/$roomId');
- },
+ onTap: client.userID == profile.userId
+ ? null
+ : () async {
+ final router = GoRouter.of(context);
+ final roomIdResult = await showFutureLoadingDialog(
+ context: context,
+ future: () => client.startDirectChat(profile.userId),
+ );
+ final roomId = roomIdResult.result;
+ if (roomId == null) return;
+ if (context.mounted) Navigator.of(context).pop();
+ router.go('/rooms/$roomId');
+ },
child: Text(
directChatRoomId == null
? L10n.of(context).createNewChat
diff --git a/lib/widgets/fluffy_chat_app.dart b/lib/widgets/fluffy_chat_app.dart
index 4a72d07dd..af7803792 100644
--- a/lib/widgets/fluffy_chat_app.dart
+++ b/lib/widgets/fluffy_chat_app.dart
@@ -4,6 +4,7 @@ import 'package:go_router/go_router.dart';
import 'package:matrix/matrix.dart';
import 'package:shared_preferences/shared_preferences.dart';
+import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/config/routes.dart';
import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/config/themes.dart';
@@ -37,6 +38,12 @@ class FluffyChatApp extends StatelessWidget {
static final GoRouter router = GoRouter(
routes: AppRoutes.routes,
debugLogDiagnostics: true,
+ redirect: (context, state) {
+ if (state.uri.toString().startsWith(AppConfig.deepLinkPrefix)) {
+ return '/rooms/newprivatechat?deeplink=${state.uri}';
+ }
+ return null;
+ },
);
@override
diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc
index deccda1dc..b586adbbf 100644
--- a/linux/flutter/generated_plugin_registrant.cc
+++ b/linux/flutter/generated_plugin_registrant.cc
@@ -13,7 +13,6 @@
#include
#include
#include
-#include
#include
#include
#include
@@ -45,9 +44,6 @@ void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) flutter_webrtc_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterWebRTCPlugin");
flutter_web_r_t_c_plugin_register_with_registrar(flutter_webrtc_registrar);
- g_autoptr(FlPluginRegistrar) gtk_registrar =
- fl_plugin_registry_get_registrar_for_plugin(registry, "GtkPlugin");
- gtk_plugin_register_with_registrar(gtk_registrar);
g_autoptr(FlPluginRegistrar) handy_window_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "HandyWindowPlugin");
handy_window_plugin_register_with_registrar(handy_window_registrar);
diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake
index 53413056c..95cd5f009 100644
--- a/linux/flutter/generated_plugins.cmake
+++ b/linux/flutter/generated_plugins.cmake
@@ -10,7 +10,6 @@ list(APPEND FLUTTER_PLUGIN_LIST
file_selector_linux
flutter_secure_storage_linux
flutter_webrtc
- gtk
handy_window
record_linux
screen_retriever_linux
diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift
index 0e1ab0cac..a334837f6 100644
--- a/macos/Flutter/GeneratedPluginRegistrant.swift
+++ b/macos/Flutter/GeneratedPluginRegistrant.swift
@@ -5,7 +5,6 @@
import FlutterMacOS
import Foundation
-import app_links
import audio_session
import desktop_drop
import desktop_webview_window
@@ -36,7 +35,6 @@ import window_manager
import window_to_front
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
- AppLinksMacosPlugin.register(with: registry.registrar(forPlugin: "AppLinksMacosPlugin"))
AudioSessionPlugin.register(with: registry.registrar(forPlugin: "AudioSessionPlugin"))
DesktopDropPlugin.register(with: registry.registrar(forPlugin: "DesktopDropPlugin"))
DesktopWebviewWindowPlugin.register(with: registry.registrar(forPlugin: "DesktopWebviewWindowPlugin"))
diff --git a/pubspec.lock b/pubspec.lock
index 982b471c2..78d1b7508 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -41,38 +41,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.0.3"
- app_links:
- dependency: "direct main"
- description:
- name: app_links
- sha256: "5f88447519add627fe1cbcab4fd1da3d4fed15b9baf29f28b22535c95ecee3e8"
- url: "https://pub.dev"
- source: hosted
- version: "6.4.1"
- app_links_linux:
- dependency: transitive
- description:
- name: app_links_linux
- sha256: f5f7173a78609f3dfd4c2ff2c95bd559ab43c80a87dc6a095921d96c05688c81
- url: "https://pub.dev"
- source: hosted
- version: "1.0.3"
- app_links_platform_interface:
- dependency: transitive
- description:
- name: app_links_platform_interface
- sha256: "05f5379577c513b534a29ddea68176a4d4802c46180ee8e2e966257158772a3f"
- url: "https://pub.dev"
- source: hosted
- version: "2.0.2"
- app_links_web:
- dependency: transitive
- description:
- name: app_links_web
- sha256: af060ed76183f9e2b87510a9480e56a5352b6c249778d07bd2c95fc35632a555
- url: "https://pub.dev"
- source: hosted
- version: "1.0.4"
archive:
dependency: "direct main"
description:
@@ -807,14 +775,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.2.8"
- gtk:
- dependency: transitive
- description:
- name: gtk
- sha256: e8ce9ca4b1df106e4d72dad201d345ea1a036cc12c360f1a7d5a758f78ffa42c
- url: "https://pub.dev"
- source: hosted
- version: "2.1.0"
handy_window:
dependency: "direct main"
description:
diff --git a/pubspec.yaml b/pubspec.yaml
index aeeb8e91c..99115e514 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -12,7 +12,6 @@ environment:
dependencies:
animations: ^2.1.1
- app_links: ^6.4.1
archive: ^4.0.7
async: ^2.11.0
badges: ^3.1.2
diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc
index 0e75c6434..42b9ae094 100644
--- a/windows/flutter/generated_plugin_registrant.cc
+++ b/windows/flutter/generated_plugin_registrant.cc
@@ -6,7 +6,6 @@
#include "generated_plugin_registrant.h"
-#include
#include
#include
#include
@@ -26,8 +25,6 @@
#include
void RegisterPlugins(flutter::PluginRegistry* registry) {
- AppLinksPluginCApiRegisterWithRegistrar(
- registry->GetRegistrarForPlugin("AppLinksPluginCApi"));
DesktopDropPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("DesktopDropPlugin"));
DesktopWebviewWindowPluginRegisterWithRegistrar(
diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake
index 307090774..93b91c2eb 100644
--- a/windows/flutter/generated_plugins.cmake
+++ b/windows/flutter/generated_plugins.cmake
@@ -3,7 +3,6 @@
#
list(APPEND FLUTTER_PLUGIN_LIST
- app_links
desktop_drop
desktop_webview_window
dynamic_color