⚗️ Markdown embed content

This commit is contained in:
2024-08-03 12:29:13 +08:00
parent 989b5babd9
commit 87bb37ac01
8 changed files with 67 additions and 14 deletions

View File

@ -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

View File

@ -35,7 +35,7 @@ class SilverRelativeList extends StatelessWidget {
context: context,
builder: (context) =>
AccountProfilePopup(
account: element.related,
name: element.related.name,
),
);
},

View File

@ -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,
),
);
},

View File

@ -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,
),
);
},

View File

@ -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;
}
}

View File

@ -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,
),
);
},

View File

@ -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,
),
);
},