Merge pull request #2676 from krille-chan/krille/minor-fixes

chore: Move website back to fluffychat.im
This commit is contained in:
Krille-chan 2026-03-09 18:21:44 +01:00 committed by GitHub
commit 8571c42ba4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 101 additions and 128 deletions

View file

@ -8,6 +8,7 @@ on:
jobs: jobs:
notify: 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 runs-on: ubuntu-latest
steps: steps:
- name: Send notification to Matrix room - name: Send notification to Matrix room

View file

@ -106,7 +106,7 @@
<action android:name="android.intent.action.VIEW" /> <action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" /> <category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="chat.fluffy" android:host="login"/> <data android:scheme="im.fluffychat" android:host="login"/>
</intent-filter> </intent-filter>
</activity> </activity>

View file

@ -35,7 +35,6 @@
<array> <array>
<string>ShareMedia-$(PRODUCT_BUNDLE_IDENTIFIER)</string> <string>ShareMedia-$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<string>im.fluffychat</string> <string>im.fluffychat</string>
<string>chat.fluffy</string>
<string>matrix</string> <string>matrix</string>
</array> </array>
</dict> </dict>

View file

@ -22,15 +22,15 @@ abstract class AppConfig {
static const double columnWidth = 360.0; static const double columnWidth = 360.0;
static const String enablePushTutorial = static const String enablePushTutorial =
'https://fluffy.chat/faq/#push_without_google_services'; 'https://fluffychat.im/faq/#push_without_google_services';
static const String encryptionTutorial = 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 = 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 = 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 appId = 'im.fluffychat.FluffyChat';
static const String appOpenUrlScheme = 'chat.fluffy'; static const String appOpenUrlScheme = 'im.fluffychat';
static const String sourceCodeUrl = static const String sourceCodeUrl =
'https://github.com/krille-chan/fluffychat'; 'https://github.com/krille-chan/fluffychat';

View file

@ -170,8 +170,14 @@ abstract class AppRoutes {
), ),
GoRoute( GoRoute(
path: 'newprivatechat', path: 'newprivatechat',
pageBuilder: (context, state) => pageBuilder: (context, state) => defaultPageBuilder(
defaultPageBuilder(context, state, const NewPrivateChat()), context,
state,
NewPrivateChat(
key: ValueKey('new_chat_${state.uri.query}'),
deeplink: state.uri.queryParameters['deeplink'],
),
),
redirect: loggedOutRedirect, redirect: loggedOutRedirect,
), ),
GoRoute( GoRoute(

View file

@ -56,16 +56,16 @@ enum AppSettings<T> {
enableMatrixNativeOIDC<bool>('chat.fluffy.enable_matrix_native_oidc', false), enableMatrixNativeOIDC<bool>('chat.fluffy.enable_matrix_native_oidc', false),
presetHomeserver<String>('chat.fluffy.preset_homeserver', ''), presetHomeserver<String>('chat.fluffy.preset_homeserver', ''),
welcomeText<String>('chat.fluffy.welcome_text', ''), welcomeText<String>('chat.fluffy.welcome_text', ''),
website<String>('chat.fluffy.website_url', 'https://fluffy.chat'), website<String>('chat.fluffy.website_url', 'https://fluffychat.im'),
logoUrl<String>( logoUrl<String>(
'chat.fluffy.logo_url', 'chat.fluffy.logo_url',
'https://fluffy.chat/assets/favicon.png', 'https://fluffychat.im/assets/favicon.png',
), ),
privacyPolicy<String>( privacyPolicy<String>(
'chat.fluffy.privacy_policy_url', 'chat.fluffy.privacy_policy_url',
'https://fluffy.chat/en/privacy', 'https://fluffychat.im/en/privacy',
), ),
tos<String>('chat.fluffy.tos_url', 'https://fluffy.chat/en/tos'); tos<String>('chat.fluffy.tos_url', 'https://fluffychat.im/en/tos');
final String key; final String key;
final T defaultValue; final T defaultValue;

View file

@ -165,11 +165,11 @@ class AudioPlayerState extends State<AudioPlayerWidget> {
: null, : null,
); );
if (!kIsWeb) { final attachmentUrl = widget.event.attachmentOrThumbnailMxcUrl();
if (!kIsWeb && attachmentUrl != null) {
final tempDir = await getTemporaryDirectory(); final tempDir = await getTemporaryDirectory();
final fileName = Uri.encodeComponent( final fileName = Uri.encodeComponent(attachmentUrl.pathSegments.last);
widget.event.attachmentOrThumbnailMxcUrl()!.pathSegments.last,
);
file = File('${tempDir.path}/${fileName}_${matrixFile.name}'); file = File('${tempDir.path}/${fileName}_${matrixFile.name}');
await file.writeAsBytes(matrixFile.bytes); await file.writeAsBytes(matrixFile.bytes);

View file

@ -1,8 +1,9 @@
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:async/async.dart' show Result;
import 'package:cross_file/cross_file.dart'; 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:mime/mime.dart';
import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/config/app_config.dart';
@ -53,8 +54,9 @@ class SendFileDialogState extends State<SendFileDialog> {
} }
scaffoldMessenger.showLoadingSnackBar(l10n.prepareSendingAttachment); scaffoldMessenger.showLoadingSnackBar(l10n.prepareSendingAttachment);
Navigator.of(context, rootNavigator: false).pop(); Navigator.of(context, rootNavigator: false).pop();
final clientConfig = await widget.room.client.getConfig(); final clientConfig = await Result.capture(widget.room.client.getConfig());
final maxUploadSize = clientConfig.mUploadSize ?? 100 * 1000 * 1000; final maxUploadSize =
clientConfig.asValue?.value.mUploadSize ?? 100 * 1000 * 1000;
for (final xfile in widget.files) { for (final xfile in widget.files) {
final MatrixFile file; final MatrixFile file;

View file

@ -1,9 +1,9 @@
import 'dart:async'; import 'dart:async';
import 'dart:developer';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:app_links/app_links.dart';
import 'package:cross_file/cross_file.dart'; import 'package:cross_file/cross_file.dart';
import 'package:flutter_shortcuts_new/flutter_shortcuts_new.dart'; import 'package:flutter_shortcuts_new/flutter_shortcuts_new.dart';
import 'package:go_router/go_router.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:matrix/matrix.dart';
import 'package:receive_sharing_intent/receive_sharing_intent.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/l10n/l10n.dart';
import 'package:fluffychat/pages/chat_list/chat_list_view.dart'; import 'package:fluffychat/pages/chat_list/chat_list_view.dart';
import 'package:fluffychat/utils/localized_exception_extension.dart'; import 'package:fluffychat/utils/localized_exception_extension.dart';
@ -71,8 +72,6 @@ class ChatListController extends State<ChatList>
StreamSubscription? _intentFileStreamSubscription; StreamSubscription? _intentFileStreamSubscription;
StreamSubscription? _intentUriStreamSubscription;
late ActiveFilter activeFilter; late ActiveFilter activeFilter;
String? _activeSpaceId; String? _activeSpaceId;
@ -308,6 +307,12 @@ class ChatListController extends State<ChatList>
void _processIncomingSharedMedia(List<SharedMediaFile> files) { void _processIncomingSharedMedia(List<SharedMediaFile> files) {
if (files.isEmpty) return; if (files.isEmpty) return;
if (files.singleOrNull?.path.startsWith(AppConfig.deepLinkPrefix) == true) {
return;
}
inspect(files);
showScaffoldDialog( showScaffoldDialog(
context: context, context: context,
builder: (context) => ShareScaffoldDialog( builder: (context) => ShareScaffoldDialog(
@ -326,14 +331,6 @@ class ChatListController extends State<ChatList>
); );
} }
Future<void> _processIncomingUris(Uri? uri) async {
if (uri == null) return;
context.go('/rooms');
WidgetsBinding.instance.addPostFrameCallback((_) {
UrlLauncher(context, uri.toString()).openMatrixToUrl();
});
}
void _initReceiveSharingIntent() { void _initReceiveSharingIntent() {
if (!PlatformInfos.isMobile) return; if (!PlatformInfos.isMobile) return;
@ -347,11 +344,6 @@ class ChatListController extends State<ChatList>
_processIncomingSharedMedia, _processIncomingSharedMedia,
); );
// For receiving shared Uris
_intentUriStreamSubscription = AppLinks().uriLinkStream.listen(
_processIncomingUris,
);
if (PlatformInfos.isAndroid) { if (PlatformInfos.isAndroid) {
final shortcuts = FlutterShortcuts(); final shortcuts = FlutterShortcuts();
shortcuts.initialize().then( shortcuts.initialize().then(
@ -394,7 +386,6 @@ class ChatListController extends State<ChatList>
void dispose() { void dispose() {
_intentDataStreamSubscription?.cancel(); _intentDataStreamSubscription?.cancel();
_intentFileStreamSubscription?.cancel(); _intentFileStreamSubscription?.cancel();
_intentUriStreamSubscription?.cancel();
scrollController.removeListener(_onScroll); scrollController.removeListener(_onScroll);
super.dispose(); super.dispose();
} }

View file

@ -17,7 +17,8 @@ import 'package:fluffychat/widgets/matrix.dart';
import '../../widgets/adaptive_dialogs/user_dialog.dart'; import '../../widgets/adaptive_dialogs/user_dialog.dart';
class NewPrivateChat extends StatefulWidget { class NewPrivateChat extends StatefulWidget {
const NewPrivateChat({super.key}); final String? deeplink;
const NewPrivateChat({super.key, required this.deeplink});
@override @override
NewPrivateChatController createState() => NewPrivateChatController(); NewPrivateChatController createState() => NewPrivateChatController();
@ -33,6 +34,18 @@ class NewPrivateChatController extends State<NewPrivateChat> {
static const Duration _coolDown = Duration(milliseconds: 500); 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<void> searchUsers([String? input]) async { Future<void> searchUsers([String? input]) async {
final searchTerm = input ?? controller.text; final searchTerm = input ?? controller.text;
if (searchTerm.isEmpty) { if (searchTerm.isEmpty) {

View file

@ -85,7 +85,7 @@ class AdaptiveDialogAction extends StatelessWidget {
class AdaptiveDialogInkWell extends StatelessWidget { class AdaptiveDialogInkWell extends StatelessWidget {
final Widget child; final Widget child;
final VoidCallback onTap; final VoidCallback? onTap;
final EdgeInsets padding; final EdgeInsets padding;
const AdaptiveDialogInkWell({ const AdaptiveDialogInkWell({
@ -125,7 +125,7 @@ class AdaptiveDialogInkWell extends StatelessWidget {
class AdaptiveIconTextButton extends StatelessWidget { class AdaptiveIconTextButton extends StatelessWidget {
final String label; final String label;
final IconData icon; final IconData icon;
final VoidCallback onTap; final VoidCallback? onTap;
const AdaptiveIconTextButton({ const AdaptiveIconTextButton({
super.key, super.key,
required this.label, required this.label,

View file

@ -195,35 +195,39 @@ class UserDialog extends StatelessWidget {
AdaptiveIconTextButton( AdaptiveIconTextButton(
label: L10n.of(context).block, label: L10n.of(context).block,
icon: Icons.block_outlined, icon: Icons.block_outlined,
onTap: () { onTap: client.userID == profile.userId
final router = GoRouter.of(context); ? null
Navigator.of(context).pop(); : () {
router.go( final router = GoRouter.of(context);
'/rooms/settings/security/ignorelist', Navigator.of(context).pop();
extra: profile.userId, router.go(
); '/rooms/settings/security/ignorelist',
}, extra: profile.userId,
);
},
), ),
AdaptiveIconTextButton( AdaptiveIconTextButton(
label: L10n.of(context).report, label: L10n.of(context).report,
icon: Icons.gavel_outlined, icon: Icons.gavel_outlined,
onTap: () async { onTap: client.userID == profile.userId
Navigator.of(context).pop(); ? null
final reason = await showTextInputDialog( : () async {
context: context, Navigator.of(context).pop();
title: L10n.of(context).whyDoYouWantToReportThis, final reason = await showTextInputDialog(
okLabel: L10n.of(context).report, context: context,
cancelLabel: L10n.of(context).cancel, title: L10n.of(context).whyDoYouWantToReportThis,
hintText: L10n.of(context).reason, okLabel: L10n.of(context).report,
); cancelLabel: L10n.of(context).cancel,
if (reason == null || reason.isEmpty) return; hintText: L10n.of(context).reason,
await showFutureLoadingDialog( );
context: context, if (reason == null || reason.isEmpty) return;
future: () => Matrix.of( await showFutureLoadingDialog(
context, context: context,
).client.reportUser(profile.userId, reason), future: () => Matrix.of(
); context,
}, ).client.reportUser(profile.userId, reason),
);
},
), ),
AdaptiveIconTextButton( AdaptiveIconTextButton(
label: L10n.of(context).share, label: L10n.of(context).share,
@ -236,17 +240,19 @@ class UserDialog extends StatelessWidget {
], ],
), ),
AdaptiveDialogInkWell( AdaptiveDialogInkWell(
onTap: () async { onTap: client.userID == profile.userId
final router = GoRouter.of(context); ? null
final roomIdResult = await showFutureLoadingDialog( : () async {
context: context, final router = GoRouter.of(context);
future: () => client.startDirectChat(profile.userId), final roomIdResult = await showFutureLoadingDialog(
); context: context,
final roomId = roomIdResult.result; future: () => client.startDirectChat(profile.userId),
if (roomId == null) return; );
if (context.mounted) Navigator.of(context).pop(); final roomId = roomIdResult.result;
router.go('/rooms/$roomId'); if (roomId == null) return;
}, if (context.mounted) Navigator.of(context).pop();
router.go('/rooms/$roomId');
},
child: Text( child: Text(
directChatRoomId == null directChatRoomId == null
? L10n.of(context).createNewChat ? L10n.of(context).createNewChat

View file

@ -4,6 +4,7 @@ import 'package:go_router/go_router.dart';
import 'package:matrix/matrix.dart'; import 'package:matrix/matrix.dart';
import 'package:shared_preferences/shared_preferences.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/routes.dart';
import 'package:fluffychat/config/setting_keys.dart'; import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/config/themes.dart'; import 'package:fluffychat/config/themes.dart';
@ -37,6 +38,12 @@ class FluffyChatApp extends StatelessWidget {
static final GoRouter router = GoRouter( static final GoRouter router = GoRouter(
routes: AppRoutes.routes, routes: AppRoutes.routes,
debugLogDiagnostics: true, debugLogDiagnostics: true,
redirect: (context, state) {
if (state.uri.toString().startsWith(AppConfig.deepLinkPrefix)) {
return '/rooms/newprivatechat?deeplink=${state.uri}';
}
return null;
},
); );
@override @override

View file

@ -13,7 +13,6 @@
#include <file_selector_linux/file_selector_plugin.h> #include <file_selector_linux/file_selector_plugin.h>
#include <flutter_secure_storage_linux/flutter_secure_storage_linux_plugin.h> #include <flutter_secure_storage_linux/flutter_secure_storage_linux_plugin.h>
#include <flutter_webrtc/flutter_web_r_t_c_plugin.h> #include <flutter_webrtc/flutter_web_r_t_c_plugin.h>
#include <gtk/gtk_plugin.h>
#include <handy_window/handy_window_plugin.h> #include <handy_window/handy_window_plugin.h>
#include <record_linux/record_linux_plugin.h> #include <record_linux/record_linux_plugin.h>
#include <screen_retriever_linux/screen_retriever_linux_plugin.h> #include <screen_retriever_linux/screen_retriever_linux_plugin.h>
@ -45,9 +44,6 @@ void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) flutter_webrtc_registrar = g_autoptr(FlPluginRegistrar) flutter_webrtc_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterWebRTCPlugin"); fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterWebRTCPlugin");
flutter_web_r_t_c_plugin_register_with_registrar(flutter_webrtc_registrar); 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 = g_autoptr(FlPluginRegistrar) handy_window_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "HandyWindowPlugin"); fl_plugin_registry_get_registrar_for_plugin(registry, "HandyWindowPlugin");
handy_window_plugin_register_with_registrar(handy_window_registrar); handy_window_plugin_register_with_registrar(handy_window_registrar);

View file

@ -10,7 +10,6 @@ list(APPEND FLUTTER_PLUGIN_LIST
file_selector_linux file_selector_linux
flutter_secure_storage_linux flutter_secure_storage_linux
flutter_webrtc flutter_webrtc
gtk
handy_window handy_window
record_linux record_linux
screen_retriever_linux screen_retriever_linux

View file

@ -5,7 +5,6 @@
import FlutterMacOS import FlutterMacOS
import Foundation import Foundation
import app_links
import audio_session import audio_session
import desktop_drop import desktop_drop
import desktop_webview_window import desktop_webview_window
@ -36,7 +35,6 @@ import window_manager
import window_to_front import window_to_front
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
AppLinksMacosPlugin.register(with: registry.registrar(forPlugin: "AppLinksMacosPlugin"))
AudioSessionPlugin.register(with: registry.registrar(forPlugin: "AudioSessionPlugin")) AudioSessionPlugin.register(with: registry.registrar(forPlugin: "AudioSessionPlugin"))
DesktopDropPlugin.register(with: registry.registrar(forPlugin: "DesktopDropPlugin")) DesktopDropPlugin.register(with: registry.registrar(forPlugin: "DesktopDropPlugin"))
DesktopWebviewWindowPlugin.register(with: registry.registrar(forPlugin: "DesktopWebviewWindowPlugin")) DesktopWebviewWindowPlugin.register(with: registry.registrar(forPlugin: "DesktopWebviewWindowPlugin"))

View file

@ -41,38 +41,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.3" 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: archive:
dependency: "direct main" dependency: "direct main"
description: description:
@ -807,14 +775,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.2.8" version: "0.2.8"
gtk:
dependency: transitive
description:
name: gtk
sha256: e8ce9ca4b1df106e4d72dad201d345ea1a036cc12c360f1a7d5a758f78ffa42c
url: "https://pub.dev"
source: hosted
version: "2.1.0"
handy_window: handy_window:
dependency: "direct main" dependency: "direct main"
description: description:

View file

@ -12,7 +12,6 @@ environment:
dependencies: dependencies:
animations: ^2.1.1 animations: ^2.1.1
app_links: ^6.4.1
archive: ^4.0.7 archive: ^4.0.7
async: ^2.11.0 async: ^2.11.0
badges: ^3.1.2 badges: ^3.1.2

View file

@ -6,7 +6,6 @@
#include "generated_plugin_registrant.h" #include "generated_plugin_registrant.h"
#include <app_links/app_links_plugin_c_api.h>
#include <desktop_drop/desktop_drop_plugin.h> #include <desktop_drop/desktop_drop_plugin.h>
#include <desktop_webview_window/desktop_webview_window_plugin.h> #include <desktop_webview_window/desktop_webview_window_plugin.h>
#include <dynamic_color/dynamic_color_plugin_c_api.h> #include <dynamic_color/dynamic_color_plugin_c_api.h>
@ -26,8 +25,6 @@
#include <window_to_front/window_to_front_plugin.h> #include <window_to_front/window_to_front_plugin.h>
void RegisterPlugins(flutter::PluginRegistry* registry) { void RegisterPlugins(flutter::PluginRegistry* registry) {
AppLinksPluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("AppLinksPluginCApi"));
DesktopDropPluginRegisterWithRegistrar( DesktopDropPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("DesktopDropPlugin")); registry->GetRegistrarForPlugin("DesktopDropPlugin"));
DesktopWebviewWindowPluginRegisterWithRegistrar( DesktopWebviewWindowPluginRegisterWithRegistrar(

View file

@ -3,7 +3,6 @@
# #
list(APPEND FLUTTER_PLUGIN_LIST list(APPEND FLUTTER_PLUGIN_LIST
app_links
desktop_drop desktop_drop
desktop_webview_window desktop_webview_window
dynamic_color dynamic_color