⚗️ Markdown embed content
This commit is contained in:
@ -8,9 +8,9 @@ import 'package:solian/services.dart';
|
||||
import 'package:solian/widgets/account/account_heading.dart';
|
||||
|
||||
class AccountProfilePopup extends StatefulWidget {
|
||||
final Account account;
|
||||
final String name;
|
||||
|
||||
const AccountProfilePopup({super.key, required this.account});
|
||||
const AccountProfilePopup({super.key, required this.name});
|
||||
|
||||
@override
|
||||
State<AccountProfilePopup> createState() => _AccountProfilePopupState();
|
||||
@ -21,11 +21,11 @@ class _AccountProfilePopupState extends State<AccountProfilePopup> {
|
||||
|
||||
Account? _userinfo;
|
||||
|
||||
void getUserinfo() async {
|
||||
void _getUserinfo() async {
|
||||
setState(() => _isBusy = true);
|
||||
|
||||
final client = ServiceFinder.configureClient('auth');
|
||||
final resp = await client.get('/users/${widget.account.name}');
|
||||
final resp = await client.get('/users/${widget.name}');
|
||||
if (resp.statusCode == 200) {
|
||||
_userinfo = Account.fromJson(resp.body);
|
||||
setState(() => _isBusy = false);
|
||||
@ -38,7 +38,7 @@ class _AccountProfilePopupState extends State<AccountProfilePopup> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
getUserinfo();
|
||||
_getUserinfo();
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -35,7 +35,7 @@ class SilverRelativeList extends StatelessWidget {
|
||||
context: context,
|
||||
builder: (context) =>
|
||||
AccountProfilePopup(
|
||||
account: element.related,
|
||||
name: element.related.name,
|
||||
),
|
||||
);
|
||||
},
|
||||
|
@ -160,7 +160,7 @@ class _ChannelMemberListPopupState extends State<ChannelMemberListPopup> {
|
||||
backgroundColor: Theme.of(context).colorScheme.surface,
|
||||
context: context,
|
||||
builder: (context) => AccountProfilePopup(
|
||||
account: element.account,
|
||||
name: element.account.name,
|
||||
),
|
||||
);
|
||||
},
|
||||
|
@ -243,7 +243,7 @@ class ChatEvent extends StatelessWidget {
|
||||
backgroundColor: Theme.of(context).colorScheme.surface,
|
||||
context: context,
|
||||
builder: (context) => AccountProfilePopup(
|
||||
account: item.sender.account,
|
||||
name: item.sender.account.name,
|
||||
),
|
||||
);
|
||||
},
|
||||
|
@ -1,8 +1,11 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_markdown_selectionarea/flutter_markdown.dart';
|
||||
import 'package:markdown/markdown.dart' as markdown;
|
||||
import 'package:markdown/markdown.dart';
|
||||
import 'package:url_launcher/url_launcher_string.dart';
|
||||
|
||||
import 'account/account_profile_popup.dart';
|
||||
|
||||
class MarkdownTextContent extends StatelessWidget {
|
||||
final String content;
|
||||
final bool isSelectable;
|
||||
@ -34,6 +37,8 @@ class MarkdownTextContent extends StatelessWidget {
|
||||
extensionSet: markdown.ExtensionSet(
|
||||
markdown.ExtensionSet.gitHubFlavored.blockSyntaxes,
|
||||
<markdown.InlineSyntax>[
|
||||
_UserNameCardInlineSyntax(),
|
||||
_CustomEmoteInlineSyntax(),
|
||||
markdown.EmojiSyntax(),
|
||||
markdown.AutolinkExtensionSyntax(),
|
||||
...markdown.ExtensionSet.gitHubFlavored.inlineSyntaxes
|
||||
@ -41,6 +46,23 @@ class MarkdownTextContent extends StatelessWidget {
|
||||
),
|
||||
onTapLink: (text, href, title) async {
|
||||
if (href == null) return;
|
||||
if (href.startsWith('solink://')) {
|
||||
final segments = href.replaceFirst('solink://', '').split('/');
|
||||
switch (segments[0]) {
|
||||
case 'users':
|
||||
showModalBottomSheet(
|
||||
useRootNavigator: true,
|
||||
isScrollControlled: true,
|
||||
backgroundColor: Theme.of(context).colorScheme.surface,
|
||||
context: context,
|
||||
builder: (context) => AccountProfilePopup(
|
||||
name: segments[1],
|
||||
),
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
await launchUrlString(
|
||||
href,
|
||||
mode: LaunchMode.externalApplication,
|
||||
@ -57,3 +79,34 @@ class MarkdownTextContent extends StatelessWidget {
|
||||
return _buildContent(context);
|
||||
}
|
||||
}
|
||||
|
||||
class _UserNameCardInlineSyntax extends InlineSyntax {
|
||||
_UserNameCardInlineSyntax() : super(r'@[a-zA-Z0-9_]+');
|
||||
|
||||
@override
|
||||
bool onMatch(markdown.InlineParser parser, Match match) {
|
||||
final alias = match[0]!;
|
||||
final anchor = markdown.Element.text('a', alias)
|
||||
..attributes['href'] = Uri.encodeFull(
|
||||
'solink://users/${alias.substring(1)}',
|
||||
);
|
||||
parser.addNode(anchor);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class _CustomEmoteInlineSyntax extends InlineSyntax {
|
||||
_CustomEmoteInlineSyntax() : super(r':([a-z0-9_+-]+):');
|
||||
|
||||
@override
|
||||
bool onMatch(markdown.InlineParser parser, Match match) {
|
||||
// final alias = match[1]!;
|
||||
// TODO mapping things...
|
||||
final element = markdown.Element.empty('img');
|
||||
element.attributes['src'] = 'https://www.twitch.tv/creatorcamp/assets/uploads/lul.png';
|
||||
parser.addNode(element);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -310,7 +310,7 @@ class _PostItemState extends State<PostItem> {
|
||||
backgroundColor: Theme.of(context).colorScheme.surface,
|
||||
context: context,
|
||||
builder: (context) => AccountProfilePopup(
|
||||
account: item.author,
|
||||
name: item.author.name,
|
||||
),
|
||||
);
|
||||
},
|
||||
|
@ -157,7 +157,7 @@ class _RealmMemberListPopupState extends State<RealmMemberListPopup> {
|
||||
backgroundColor: Theme.of(context).colorScheme.surface,
|
||||
context: context,
|
||||
builder: (context) => AccountProfilePopup(
|
||||
account: element.account,
|
||||
name: element.account.name,
|
||||
),
|
||||
);
|
||||
},
|
||||
|
Reference in New Issue
Block a user