127 lines
3.5 KiB
Dart
127 lines
3.5 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:logging/logging.dart';
|
|
import 'package:provider/provider.dart';
|
|
import 'package:url_launcher/url_launcher.dart' as ul;
|
|
|
|
import 'l10n/l10n.dart';
|
|
import 'pages/community/community.dart';
|
|
import 'pages/instance/instance.dart';
|
|
import 'pages/media_view.dart';
|
|
import 'pages/user.dart';
|
|
import 'stores/accounts_store.dart';
|
|
import 'util/goto.dart';
|
|
|
|
/// Decides where does a link link to. Either somewhere in-app:
|
|
/// opens the correct page, or outside of the app: opens in a browser
|
|
Future<void> linkLauncher({
|
|
required BuildContext context,
|
|
required String url,
|
|
required String instanceHost,
|
|
}) async {
|
|
void push(Widget Function() builder) {
|
|
goTo(context, (c) => builder());
|
|
}
|
|
|
|
final instances = context.read<AccountsStore>().instances;
|
|
|
|
final chonks = url.split('/');
|
|
if (chonks.length == 1) {
|
|
await launchLink(link: url, context: context);
|
|
return;
|
|
}
|
|
|
|
// CHECK IF LINK TO USER
|
|
if (url.startsWith('/u/')) {
|
|
return push(() =>
|
|
UserPage.fromName(instanceHost: instanceHost, username: chonks[2]));
|
|
}
|
|
|
|
// CHECK IF LINK TO COMMUNITY
|
|
if (url.startsWith('/c/')) {
|
|
await Navigator.of(context)
|
|
.push(CommunityPage.fromNameRoute(instanceHost, chonks[2]));
|
|
return;
|
|
}
|
|
|
|
// CHECK IF REDIRECTS TO A PAGE ON ONE OF ADDED INSTANCES
|
|
|
|
final instanceRegex = RegExp(r'^(?:https?:\/\/)?([\w\.-]+)(.*)$');
|
|
final match = instanceRegex.firstMatch(url);
|
|
|
|
final matchedInstance = match?.group(1);
|
|
final rest = match?.group(2);
|
|
|
|
if (matchedInstance != null && instances.any((e) => e == match?.group(1))) {
|
|
if (rest == null || rest.isEmpty || rest == '/') {
|
|
return Navigator.of(context).push<void>(InstancePage.route(instanceHost));
|
|
}
|
|
final split = rest.split('/');
|
|
switch (split[1]) {
|
|
case 'c':
|
|
return goToCommunity.byName(context, matchedInstance, split[2]);
|
|
|
|
case 'u':
|
|
return goToUser.byName(context, matchedInstance, split[2]);
|
|
|
|
case 'post':
|
|
if (split.length == 3) {
|
|
return goToPost(context, matchedInstance, int.parse(split[2]));
|
|
} else if (split.length == 5) {
|
|
// TODO: post with focus on comment thread
|
|
return goToPost(context, matchedInstance, int.parse(split[2]));
|
|
}
|
|
break;
|
|
|
|
case 'pictrs':
|
|
return push(() => MediaViewPage(url));
|
|
|
|
case 'communities':
|
|
// TODO: put here push to communities page
|
|
return;
|
|
|
|
case 'modlog':
|
|
// TODO: put here push to modlog
|
|
return;
|
|
case 'inbox':
|
|
// TODO: put here push to inbox
|
|
return;
|
|
case 'search':
|
|
// TODO: *maybe* put here push to search. we'll see
|
|
// how much web version differs form the app
|
|
return;
|
|
case 'create_post':
|
|
case 'create_community':
|
|
case 'sponsors':
|
|
case 'instances':
|
|
case 'docs':
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
// FALLBACK TO REGULAR LINK STUFF
|
|
|
|
await launchLink(link: url, context: context);
|
|
}
|
|
|
|
final _logger = Logger('launchLink');
|
|
|
|
/// Returns whether launching was successful.
|
|
Future<bool> launchLink({
|
|
required String link,
|
|
required BuildContext context,
|
|
}) async {
|
|
final uri = Uri.tryParse(link);
|
|
if (uri != null && await ul.canLaunchUrl(uri)) {
|
|
await ul.launchUrl(uri);
|
|
return true;
|
|
} else {
|
|
_logger.warning('Failed to launch a link: $link');
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
SnackBar(content: Text(L10n.of(context).cannot_open_in_browser)),
|
|
);
|
|
return false;
|
|
}
|
|
}
|