fix: переход по ссылкам и диплинки с миниапов

This commit is contained in:
Jganenokk
2026-08-20 22:22:35 +07:00
parent 2e8abe7e47
commit fcf9f12f95
3 changed files with 58 additions and 2 deletions
+15
View File
@@ -6,6 +6,21 @@ import 'package:url_launcher/url_launcher.dart';
import '../../frontend/widgets/custom_notification.dart'; import '../../frontend/widgets/custom_notification.dart';
import '../../frontend/widgets/max_link_handler.dart'; import '../../frontend/widgets/max_link_handler.dart';
const Set<String> _webViewSchemes = {
'http',
'https',
'about',
'data',
'blob',
'javascript',
'file',
};
bool leavesWebView(String? scheme) {
if (scheme == null || scheme.isEmpty) return false;
return !_webViewSchemes.contains(scheme.toLowerCase());
}
Future<void> openExternalUrl(BuildContext context, String url) async { Future<void> openExternalUrl(BuildContext context, String url) async {
if (await tryHandleMaxLink(context, url)) return; if (await tryHandleMaxLink(context, url)) return;
if (!context.mounted) return; if (!context.mounted) return;
@@ -182,8 +182,13 @@ class _WebAppScreenState extends State<WebAppScreen> {
return NavigationActionPolicy.CANCEL; return NavigationActionPolicy.CANCEL;
} }
final handler = widget.shouldOverrideUrlLoading; final handler = widget.shouldOverrideUrlLoading;
if (handler == null) return NavigationActionPolicy.ALLOW; if (handler != null) return handler(controller, action, _launch?.url);
return handler(controller, action, _launch?.url);
if (uri != null && leavesWebView(uri.scheme)) {
if (mounted) await openExternalUrl(context, uri.toString());
return NavigationActionPolicy.CANCEL;
}
return NavigationActionPolicy.ALLOW;
} }
@override @override
+36
View File
@@ -0,0 +1,36 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:komet/core/links/max_link.dart';
import 'package:komet/core/utils/link_opener.dart';
void main() {
group('leavesWebView', () {
test('keeps page navigation inside the web view', () {
for (final scheme in [
'http',
'https',
'HTTPS',
'about',
'data',
'blob',
]) {
expect(leavesWebView(scheme), isFalse, reason: scheme);
}
});
test('hands app schemes over to the app', () {
for (final scheme in ['max', 'MAX', 'komet', 'tel', 'mailto', 'intent']) {
expect(leavesWebView(scheme), isTrue, reason: scheme);
}
});
test('treats a missing scheme as in-page', () {
expect(leavesWebView(null), isFalse);
expect(leavesWebView(''), isFalse);
});
});
test('a max deep link from a web view resolves to in-app content', () {
expect(MaxLink.parse('max://max.ru/somechannel'), isA<MaxContentLink>());
expect(MaxLink.isMaxLink('max://max.ru/?cid=424242'), isTrue);
});
}