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:
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

View file

@ -106,7 +106,7 @@
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<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>
</activity>

View file

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

View file

@ -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';

View file

@ -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(

View file

@ -56,16 +56,16 @@ enum AppSettings<T> {
enableMatrixNativeOIDC<bool>('chat.fluffy.enable_matrix_native_oidc', false),
presetHomeserver<String>('chat.fluffy.preset_homeserver', ''),
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>(
'chat.fluffy.logo_url',
'https://fluffy.chat/assets/favicon.png',
'https://fluffychat.im/assets/favicon.png',
),
privacyPolicy<String>(
'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 T defaultValue;

View file

@ -165,11 +165,11 @@ class AudioPlayerState extends State<AudioPlayerWidget> {
: 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);

View file

@ -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<SendFileDialog> {
}
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;

View file

@ -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<ChatList>
StreamSubscription? _intentFileStreamSubscription;
StreamSubscription? _intentUriStreamSubscription;
late ActiveFilter activeFilter;
String? _activeSpaceId;
@ -308,6 +307,12 @@ class ChatListController extends State<ChatList>
void _processIncomingSharedMedia(List<SharedMediaFile> 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<ChatList>
);
}
Future<void> _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<ChatList>
_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<ChatList>
void dispose() {
_intentDataStreamSubscription?.cancel();
_intentFileStreamSubscription?.cancel();
_intentUriStreamSubscription?.cancel();
scrollController.removeListener(_onScroll);
super.dispose();
}

View file

@ -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<NewPrivateChat> {
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 {
final searchTerm = input ?? controller.text;
if (searchTerm.isEmpty) {

View file

@ -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,

View file

@ -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

View file

@ -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

View file

@ -13,7 +13,6 @@
#include <file_selector_linux/file_selector_plugin.h>
#include <flutter_secure_storage_linux/flutter_secure_storage_linux_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 <record_linux/record_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 =
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);

View file

@ -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

View file

@ -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"))

View file

@ -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:

View file

@ -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

View file

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

View file

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