fix: Open URIs

This commit is contained in:
Christian Pauly 2021-05-16 16:38:52 +02:00
parent 584c8734be
commit 6d7c52c61f
5 changed files with 63 additions and 9 deletions

View File

@ -55,6 +55,12 @@ class FluffyChatApp extends StatelessWidget {
const FluffyChatApp({Key key, this.testWidget, this.testClient}) const FluffyChatApp({Key key, this.testWidget, this.testClient})
: super(key: key); : super(key: key);
/// getInitialLink may rereturn the value multiple times if this view is
/// opened multiple times for example if the user logs out after they logged
/// in with qr code or magic link.
static bool gotInitialLink = false;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return AdaptiveTheme( return AdaptiveTheme(

View File

@ -13,6 +13,8 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'package:future_loading_dialog/future_loading_dialog.dart';
import 'package:receive_sharing_intent/receive_sharing_intent.dart'; import 'package:receive_sharing_intent/receive_sharing_intent.dart';
import 'package:uni_links/uni_links.dart';
import '../main.dart';
import 'widgets/matrix.dart'; import 'widgets/matrix.dart';
import '../utils/matrix_file_extension.dart'; import '../utils/matrix_file_extension.dart';
import '../utils/url_launcher.dart'; import '../utils/url_launcher.dart';
@ -35,6 +37,8 @@ class ChatListController extends State<ChatList> {
StreamSubscription _intentFileStreamSubscription; StreamSubscription _intentFileStreamSubscription;
StreamSubscription _intentUriStreamSubscription;
final selectedRoomIds = <String>{}; final selectedRoomIds = <String>{};
void _processIncomingSharedFiles(List<SharedMediaFile> files) { void _processIncomingSharedFiles(List<SharedMediaFile> files) {
@ -57,7 +61,6 @@ class ChatListController extends State<ChatList> {
if (text.toLowerCase().startsWith(AppConfig.inviteLinkPrefix) || if (text.toLowerCase().startsWith(AppConfig.inviteLinkPrefix) ||
(text.toLowerCase().startsWith(AppConfig.schemePrefix) && (text.toLowerCase().startsWith(AppConfig.schemePrefix) &&
!RegExp(r'\s').hasMatch(text))) { !RegExp(r'\s').hasMatch(text))) {
UrlLauncher(context, text).openMatrixToUrl();
return; return;
} }
Matrix.of(context).shareContent = { Matrix.of(context).shareContent = {
@ -66,6 +69,17 @@ class ChatListController extends State<ChatList> {
}; };
} }
void _processIncomingUris(String text) async {
if (text == null || !text.startsWith(AppConfig.appOpenUrlScheme)) return;
if (text.toLowerCase().startsWith(AppConfig.inviteLinkPrefix) ||
(text.toLowerCase().startsWith(AppConfig.schemePrefix) &&
!RegExp(r'\s').hasMatch(text))) {
AdaptivePageLayout.of(context).popUntilIsFirst();
UrlLauncher(context, text).openMatrixToUrl();
return;
}
}
void _initReceiveSharingIntent() { void _initReceiveSharingIntent() {
if (!PlatformInfos.isMobile) return; if (!PlatformInfos.isMobile) return;
@ -82,6 +96,13 @@ class ChatListController extends State<ChatList> {
// For sharing or opening urls/text coming from outside the app while the app is closed // For sharing or opening urls/text coming from outside the app while the app is closed
ReceiveSharingIntent.getInitialText().then(_processIncomingSharedText); ReceiveSharingIntent.getInitialText().then(_processIncomingSharedText);
// For receiving shared Uris
_intentDataStreamSubscription = linkStream.listen(_processIncomingUris);
if (FluffyChatApp.gotInitialLink == false) {
FluffyChatApp.gotInitialLink = true;
getInitialLink().then(_processIncomingUris);
}
} }
@override @override
@ -94,6 +115,7 @@ class ChatListController extends State<ChatList> {
void dispose() { void dispose() {
_intentDataStreamSubscription?.cancel(); _intentDataStreamSubscription?.cancel();
_intentFileStreamSubscription?.cancel(); _intentFileStreamSubscription?.cancel();
_intentUriStreamSubscription?.cancel();
super.dispose(); super.dispose();
} }

View File

@ -7,13 +7,14 @@ import 'package:fluffychat/views/widgets/matrix.dart';
import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/config/setting_keys.dart'; import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/utils/platform_infos.dart'; import 'package:fluffychat/utils/platform_infos.dart';
import 'package:uni_links/uni_links.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'package:future_loading_dialog/future_loading_dialog.dart';
import 'package:receive_sharing_intent/receive_sharing_intent.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
import '../main.dart';
import '../utils/localized_exception_extension.dart'; import '../utils/localized_exception_extension.dart';
import 'package:universal_html/html.dart' as html; import 'package:universal_html/html.dart' as html;
@ -41,24 +42,27 @@ class HomeserverPickerController extends State<HomeserverPicker> {
); );
} }
void _processIncomingSharedText(String text) async { void _processIncomingUris(String text) async {
if (text == null || !text.startsWith(AppConfig.appOpenUrlScheme)) return; if (text == null || !text.startsWith(AppConfig.appOpenUrlScheme)) return;
AdaptivePageLayout.of(context).popUntilIsFirst(); AdaptivePageLayout.of(context).popUntilIsFirst();
final token = Uri.parse(text).queryParameters['loginToken']; final token = Uri.parse(text).queryParameters['loginToken'];
_loginWithToken(token); if (token != null) _loginWithToken(token);
} }
void _initReceiveSharingContent() { void _initReceiveUri() {
if (!PlatformInfos.isMobile) return; if (!PlatformInfos.isMobile) return;
_intentDataStreamSubscription = // For receiving shared Uris
ReceiveSharingIntent.getTextStream().listen(_processIncomingSharedText); _intentDataStreamSubscription = linkStream.listen(_processIncomingUris);
ReceiveSharingIntent.getInitialText().then(_processIncomingSharedText); if (FluffyChatApp.gotInitialLink == false) {
FluffyChatApp.gotInitialLink = true;
getInitialLink().then(_processIncomingUris);
}
} }
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_initReceiveSharingContent(); _initReceiveUri();
if (kIsWeb) { if (kIsWeb) {
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
final token = final token =

View File

@ -1103,6 +1103,27 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.3.0" version: "1.3.0"
uni_links:
dependency: "direct main"
description:
name: uni_links
url: "https://pub.dartlang.org"
source: hosted
version: "0.5.1"
uni_links_platform_interface:
dependency: transitive
description:
name: uni_links_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
uni_links_web:
dependency: transitive
description:
name: uni_links_web
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.0"
unifiedpush: unifiedpush:
dependency: "direct main" dependency: "direct main"
description: description:

View File

@ -66,6 +66,7 @@ dependencies:
sqflite: ^2.0.0+3 # Still used to obtain the database location sqflite: ^2.0.0+3 # Still used to obtain the database location
sqlite3: ^1.0.0 sqlite3: ^1.0.0
swipe_to_action: ^0.1.0 swipe_to_action: ^0.1.0
uni_links: ^0.5.1
unifiedpush: ^1.0.2 unifiedpush: ^1.0.2
universal_html: ^2.0.8 universal_html: ^2.0.8
url_launcher: ^6.0.3 url_launcher: ^6.0.3