Merge pull request #37 from krawieck/link-handling
This commit is contained in:
commit
ba8b2cd55c
|
@ -31,7 +31,10 @@ class CommunitiesListPage extends StatelessWidget {
|
|||
subtitle: communities[i].description != null
|
||||
? Opacity(
|
||||
opacity: 0.5,
|
||||
child: MarkdownText(communities[i].description),
|
||||
child: MarkdownText(
|
||||
communities[i].description,
|
||||
instanceUrl: communities[i].instanceUrl,
|
||||
),
|
||||
)
|
||||
: null,
|
||||
onTap: () => goToCommunity.byId(
|
||||
|
|
|
@ -433,7 +433,8 @@ class _AboutTab extends StatelessWidget {
|
|||
if (community.description != null) ...[
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15),
|
||||
child: MarkdownText(community.description),
|
||||
child: MarkdownText(community.description,
|
||||
instanceUrl: community.instanceUrl),
|
||||
),
|
||||
_Divider(),
|
||||
],
|
||||
|
|
|
@ -208,7 +208,9 @@ class InstancePage extends HookWidget {
|
|||
Center(child: Text('comments go here')),
|
||||
],
|
||||
),
|
||||
_AboutTab(site, communitiesFuture: communitiesFuture),
|
||||
_AboutTab(site,
|
||||
communitiesFuture: communitiesFuture,
|
||||
instanceUrl: instanceUrl),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
@ -241,9 +243,12 @@ class _SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
|
|||
class _AboutTab extends HookWidget {
|
||||
final FullSiteView site;
|
||||
final Future<List<CommunityView>> communitiesFuture;
|
||||
final String instanceUrl;
|
||||
|
||||
const _AboutTab(this.site, {@required this.communitiesFuture})
|
||||
: assert(communitiesFuture != null);
|
||||
const _AboutTab(this.site,
|
||||
{@required this.communitiesFuture, @required this.instanceUrl})
|
||||
: assert(communitiesFuture != null),
|
||||
assert(instanceUrl != null);
|
||||
|
||||
void goToUser(int id) {
|
||||
print('GO TO USER $id');
|
||||
|
@ -280,7 +285,10 @@ class _AboutTab extends HookWidget {
|
|||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 15),
|
||||
child: MarkdownText(site.site.description),
|
||||
child: MarkdownText(
|
||||
site.site.description,
|
||||
instanceUrl: instanceUrl,
|
||||
),
|
||||
),
|
||||
_Divider(),
|
||||
SizedBox(
|
||||
|
@ -356,7 +364,9 @@ class _AboutTab extends HookWidget {
|
|||
e.preferredUsername.isEmpty)
|
||||
? '@${e.name}'
|
||||
: e.preferredUsername),
|
||||
subtitle: e.bio != null ? MarkdownText(e.bio) : null,
|
||||
subtitle: e.bio != null
|
||||
? MarkdownText(e.bio, instanceUrl: instanceUrl)
|
||||
: null,
|
||||
onTap: () => goToUser(e.id),
|
||||
leading: e.avatar != null
|
||||
? CachedNetworkImage(
|
||||
|
|
|
@ -18,6 +18,15 @@ class UserPage extends HookWidget {
|
|||
.getUserDetails(
|
||||
userId: userId, savedOnly: true, sort: SortType.active)
|
||||
.then((res) => res.user);
|
||||
UserPage.fromName({@required this.instanceUrl, @required String username})
|
||||
: assert(instanceUrl != null),
|
||||
assert(username != null),
|
||||
userId = null,
|
||||
_userView = LemmyApi(instanceUrl)
|
||||
.v1
|
||||
.getUserDetails(
|
||||
username: username, savedOnly: true, sort: SortType.active)
|
||||
.then((res) => res.user);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
|
|
@ -2,6 +2,7 @@ import 'package:cached_network_image/cached_network_image.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:lemmy_api_client/lemmy_api_client.dart';
|
||||
|
||||
import '../util/api_extensions.dart';
|
||||
import '../widgets/markdown_text.dart';
|
||||
|
||||
class UsersListPage extends StatelessWidget {
|
||||
|
@ -35,7 +36,10 @@ class UsersListPage extends StatelessWidget {
|
|||
subtitle: users[i].bio != null
|
||||
? Opacity(
|
||||
opacity: 0.5,
|
||||
child: MarkdownText(users[i].bio),
|
||||
child: MarkdownText(
|
||||
users[i].bio,
|
||||
instanceUrl: users[i].instanceUrl,
|
||||
),
|
||||
)
|
||||
: null,
|
||||
onTap: () => goToUser(context, users[i].id),
|
||||
|
|
|
@ -1,8 +1,113 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:url_launcher/url_launcher.dart' as ul;
|
||||
|
||||
Future<void> urlLauncher(String url) async {
|
||||
import 'pages/community.dart';
|
||||
import 'pages/full_post.dart';
|
||||
import 'pages/instance.dart';
|
||||
import 'pages/user.dart';
|
||||
import 'stores/accounts_store.dart';
|
||||
|
||||
Future<void> linkLauncher({
|
||||
@required BuildContext context,
|
||||
@required String url,
|
||||
@required String instanceUrl,
|
||||
}) async {
|
||||
push(Widget Function() builder) {
|
||||
Navigator.of(context).push(MaterialPageRoute(builder: (c) => builder()));
|
||||
}
|
||||
|
||||
final instances = context.read<AccountsStore>().users.keys.toList();
|
||||
|
||||
final chonks = url.split('/');
|
||||
|
||||
// CHECK IF LINK TO USER
|
||||
if (chonks[1] == 'u') {
|
||||
return push(
|
||||
() => UserPage.fromName(instanceUrl: instanceUrl, username: chonks[2]));
|
||||
}
|
||||
|
||||
// CHECK IF LINK TO COMMUNITY
|
||||
if (chonks[1] == 'c') {
|
||||
return push(() => CommunityPage.fromName(
|
||||
communityName: chonks[2], instanceUrl: instanceUrl));
|
||||
}
|
||||
|
||||
// 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.isEmpty || rest == '/') {
|
||||
return push(() => InstancePage(instanceUrl: matchedInstance));
|
||||
}
|
||||
final split = rest.split('/');
|
||||
switch (split[1]) {
|
||||
case 'c':
|
||||
return push(() => CommunityPage.fromName(
|
||||
communityName: split[2], instanceUrl: matchedInstance));
|
||||
|
||||
case 'u':
|
||||
return push(() => UserPage.fromName(
|
||||
instanceUrl: matchedInstance, username: split[2]));
|
||||
|
||||
case 'post':
|
||||
if (split.length == 3) {
|
||||
return push(() => FullPostPage(
|
||||
id: int.parse(split[2]), instanceUrl: matchedInstance));
|
||||
} else if (split.length == 5) {
|
||||
// TODO: post with focus on comment thread
|
||||
print('comment in post');
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'pictrs':
|
||||
// TODO: put here push to media view
|
||||
print('pictrs');
|
||||
return;
|
||||
|
||||
case 'communities':
|
||||
// TODO: put here push to communities page
|
||||
print('communities');
|
||||
return;
|
||||
|
||||
case 'modlog':
|
||||
// TODO: put here push to modlog
|
||||
print('modlog');
|
||||
return;
|
||||
case 'inbox':
|
||||
// TODO: put here push to inbox
|
||||
print('inbox');
|
||||
return;
|
||||
case 'search':
|
||||
// TODO: *maybe* put here push to search. we'll see
|
||||
// how much web version differs form the app
|
||||
print('search');
|
||||
return;
|
||||
case 'create_post':
|
||||
case 'create_community':
|
||||
case 'sponsors':
|
||||
case 'instances':
|
||||
case 'docs':
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// FALLBACK TO REGULAR LINK STUFF
|
||||
|
||||
return openInBrowser(url);
|
||||
}
|
||||
|
||||
Future<void> openInBrowser(String url) async {
|
||||
if (await ul.canLaunch(url)) {
|
||||
await ul.launch(url);
|
||||
return await ul.launch(url);
|
||||
} else {
|
||||
throw Exception();
|
||||
// TODO: handle opening links to stuff in app
|
||||
|
|
|
@ -169,7 +169,9 @@ class Comment extends StatelessWidget {
|
|||
style: TextStyle(fontStyle: FontStyle.italic),
|
||||
));
|
||||
} else {
|
||||
return Flexible(child: MarkdownText(commentTree.comment.content));
|
||||
return Flexible(
|
||||
child: MarkdownText(commentTree.comment.content,
|
||||
instanceUrl: commentTree.comment.instanceUrl));
|
||||
}
|
||||
}();
|
||||
|
||||
|
|
|
@ -6,20 +6,22 @@ import 'package:markdown/markdown.dart' as md;
|
|||
import '../url_launcher.dart';
|
||||
|
||||
class MarkdownText extends StatelessWidget {
|
||||
final String instanceUrl;
|
||||
final String text;
|
||||
MarkdownText(this.text);
|
||||
MarkdownText(this.text, {@required this.instanceUrl})
|
||||
: assert(instanceUrl != null);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => MarkdownBody(
|
||||
data: text,
|
||||
extensionSet: md.ExtensionSet.gitHubWeb,
|
||||
onTapLink: (href) {
|
||||
urlLauncher(href)
|
||||
linkLauncher(context: context, url: href, instanceUrl: instanceUrl)
|
||||
.catchError((e) => Scaffold.of(context).showSnackBar(SnackBar(
|
||||
content: Row(
|
||||
children: [
|
||||
Icon(Icons.warning),
|
||||
Text("couldn't open link"),
|
||||
Text("couldn't open link, ${e.toString()}"),
|
||||
],
|
||||
),
|
||||
)));
|
||||
|
|
|
@ -40,8 +40,6 @@ class Post extends StatelessWidget {
|
|||
|
||||
// == ACTIONS ==
|
||||
|
||||
void _openLink() => urlLauncher(post.url);
|
||||
|
||||
void _openFullImage() {
|
||||
// TODO: fullscreen media view
|
||||
print('OPEN FULL IMAGE');
|
||||
|
@ -146,6 +144,8 @@ class Post extends StatelessWidget {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
void _openLink() =>
|
||||
linkLauncher(context: context, url: post.url, instanceUrl: instanceUrl);
|
||||
|
||||
final urlDomain = () {
|
||||
if (post.url == null) return null;
|
||||
|
@ -438,7 +438,7 @@ class Post extends StatelessWidget {
|
|||
if (post.body != null)
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(10),
|
||||
child: MarkdownText(post.body)),
|
||||
child: MarkdownText(post.body, instanceUrl: instanceUrl)),
|
||||
actions(),
|
||||
],
|
||||
),
|
||||
|
|
Loading…
Reference in New Issue