⚗️ Markdown embed content
This commit is contained in:
parent
989b5babd9
commit
87bb37ac01
@ -8,9 +8,9 @@ import 'package:solian/services.dart';
|
|||||||
import 'package:solian/widgets/account/account_heading.dart';
|
import 'package:solian/widgets/account/account_heading.dart';
|
||||||
|
|
||||||
class AccountProfilePopup extends StatefulWidget {
|
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
|
@override
|
||||||
State<AccountProfilePopup> createState() => _AccountProfilePopupState();
|
State<AccountProfilePopup> createState() => _AccountProfilePopupState();
|
||||||
@ -21,11 +21,11 @@ class _AccountProfilePopupState extends State<AccountProfilePopup> {
|
|||||||
|
|
||||||
Account? _userinfo;
|
Account? _userinfo;
|
||||||
|
|
||||||
void getUserinfo() async {
|
void _getUserinfo() async {
|
||||||
setState(() => _isBusy = true);
|
setState(() => _isBusy = true);
|
||||||
|
|
||||||
final client = ServiceFinder.configureClient('auth');
|
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) {
|
if (resp.statusCode == 200) {
|
||||||
_userinfo = Account.fromJson(resp.body);
|
_userinfo = Account.fromJson(resp.body);
|
||||||
setState(() => _isBusy = false);
|
setState(() => _isBusy = false);
|
||||||
@ -38,7 +38,7 @@ class _AccountProfilePopupState extends State<AccountProfilePopup> {
|
|||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
getUserinfo();
|
_getUserinfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -35,7 +35,7 @@ class SilverRelativeList extends StatelessWidget {
|
|||||||
context: context,
|
context: context,
|
||||||
builder: (context) =>
|
builder: (context) =>
|
||||||
AccountProfilePopup(
|
AccountProfilePopup(
|
||||||
account: element.related,
|
name: element.related.name,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -160,7 +160,7 @@ class _ChannelMemberListPopupState extends State<ChannelMemberListPopup> {
|
|||||||
backgroundColor: Theme.of(context).colorScheme.surface,
|
backgroundColor: Theme.of(context).colorScheme.surface,
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => AccountProfilePopup(
|
builder: (context) => AccountProfilePopup(
|
||||||
account: element.account,
|
name: element.account.name,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -243,7 +243,7 @@ class ChatEvent extends StatelessWidget {
|
|||||||
backgroundColor: Theme.of(context).colorScheme.surface,
|
backgroundColor: Theme.of(context).colorScheme.surface,
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => AccountProfilePopup(
|
builder: (context) => AccountProfilePopup(
|
||||||
account: item.sender.account,
|
name: item.sender.account.name,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_markdown_selectionarea/flutter_markdown.dart';
|
import 'package:flutter_markdown_selectionarea/flutter_markdown.dart';
|
||||||
import 'package:markdown/markdown.dart' as markdown;
|
import 'package:markdown/markdown.dart' as markdown;
|
||||||
|
import 'package:markdown/markdown.dart';
|
||||||
import 'package:url_launcher/url_launcher_string.dart';
|
import 'package:url_launcher/url_launcher_string.dart';
|
||||||
|
|
||||||
|
import 'account/account_profile_popup.dart';
|
||||||
|
|
||||||
class MarkdownTextContent extends StatelessWidget {
|
class MarkdownTextContent extends StatelessWidget {
|
||||||
final String content;
|
final String content;
|
||||||
final bool isSelectable;
|
final bool isSelectable;
|
||||||
@ -34,6 +37,8 @@ class MarkdownTextContent extends StatelessWidget {
|
|||||||
extensionSet: markdown.ExtensionSet(
|
extensionSet: markdown.ExtensionSet(
|
||||||
markdown.ExtensionSet.gitHubFlavored.blockSyntaxes,
|
markdown.ExtensionSet.gitHubFlavored.blockSyntaxes,
|
||||||
<markdown.InlineSyntax>[
|
<markdown.InlineSyntax>[
|
||||||
|
_UserNameCardInlineSyntax(),
|
||||||
|
_CustomEmoteInlineSyntax(),
|
||||||
markdown.EmojiSyntax(),
|
markdown.EmojiSyntax(),
|
||||||
markdown.AutolinkExtensionSyntax(),
|
markdown.AutolinkExtensionSyntax(),
|
||||||
...markdown.ExtensionSet.gitHubFlavored.inlineSyntaxes
|
...markdown.ExtensionSet.gitHubFlavored.inlineSyntaxes
|
||||||
@ -41,6 +46,23 @@ class MarkdownTextContent extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
onTapLink: (text, href, title) async {
|
onTapLink: (text, href, title) async {
|
||||||
if (href == null) return;
|
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(
|
await launchUrlString(
|
||||||
href,
|
href,
|
||||||
mode: LaunchMode.externalApplication,
|
mode: LaunchMode.externalApplication,
|
||||||
@ -57,3 +79,34 @@ class MarkdownTextContent extends StatelessWidget {
|
|||||||
return _buildContent(context);
|
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,
|
backgroundColor: Theme.of(context).colorScheme.surface,
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => AccountProfilePopup(
|
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,
|
backgroundColor: Theme.of(context).colorScheme.surface,
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => AccountProfilePopup(
|
builder: (context) => AccountProfilePopup(
|
||||||
account: element.account,
|
name: element.account.name,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -79,7 +79,7 @@ PODS:
|
|||||||
- GoogleUtilities/UserDefaults (7.13.3):
|
- GoogleUtilities/UserDefaults (7.13.3):
|
||||||
- GoogleUtilities/Logger
|
- GoogleUtilities/Logger
|
||||||
- GoogleUtilities/Privacy
|
- GoogleUtilities/Privacy
|
||||||
- livekit_client (2.2.2):
|
- livekit_client (2.2.3):
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
- WebRTC-SDK (= 125.6422.04)
|
- WebRTC-SDK (= 125.6422.04)
|
||||||
- macos_window_utils (1.0.0):
|
- macos_window_utils (1.0.0):
|
||||||
@ -108,7 +108,7 @@ PODS:
|
|||||||
- screen_brightness_macos (0.1.0):
|
- screen_brightness_macos (0.1.0):
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
- Sentry/HybridSDK (8.32.0)
|
- Sentry/HybridSDK (8.32.0)
|
||||||
- sentry_flutter (8.5.0):
|
- sentry_flutter (8.6.0):
|
||||||
- Flutter
|
- Flutter
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
- Sentry/HybridSDK (= 8.32.0)
|
- Sentry/HybridSDK (= 8.32.0)
|
||||||
@ -240,7 +240,7 @@ SPEC CHECKSUMS:
|
|||||||
gal: 61e868295d28fe67ffa297fae6dacebf56fd53e1
|
gal: 61e868295d28fe67ffa297fae6dacebf56fd53e1
|
||||||
GoogleDataTransport: 6c09b596d841063d76d4288cc2d2f42cc36e1e2a
|
GoogleDataTransport: 6c09b596d841063d76d4288cc2d2f42cc36e1e2a
|
||||||
GoogleUtilities: ea963c370a38a8069cc5f7ba4ca849a60b6d7d15
|
GoogleUtilities: ea963c370a38a8069cc5f7ba4ca849a60b6d7d15
|
||||||
livekit_client: c24af2b8474a39325596e714118e05551ec5eacc
|
livekit_client: a59d8778582019242d96fe9da69d4ec48833b5ca
|
||||||
macos_window_utils: 933f91f64805e2eb91a5bd057cf97cd097276663
|
macos_window_utils: 933f91f64805e2eb91a5bd057cf97cd097276663
|
||||||
media_kit_libs_macos_video: b3e2bbec2eef97c285f2b1baa7963c67c753fb82
|
media_kit_libs_macos_video: b3e2bbec2eef97c285f2b1baa7963c67c753fb82
|
||||||
media_kit_native_event_loop: 81fd5b45192b72f8b5b69eaf5b540f45777eb8d5
|
media_kit_native_event_loop: 81fd5b45192b72f8b5b69eaf5b540f45777eb8d5
|
||||||
@ -253,7 +253,7 @@ SPEC CHECKSUMS:
|
|||||||
protocol_handler_macos: d10a6c01d6373389ffd2278013ab4c47ed6d6daa
|
protocol_handler_macos: d10a6c01d6373389ffd2278013ab4c47ed6d6daa
|
||||||
screen_brightness_macos: 2d6d3af2165592d9a55ffcd95b7550970e41ebda
|
screen_brightness_macos: 2d6d3af2165592d9a55ffcd95b7550970e41ebda
|
||||||
Sentry: 96ae1dcdf01a644bc3a3b1dc279cecaf48a833fb
|
Sentry: 96ae1dcdf01a644bc3a3b1dc279cecaf48a833fb
|
||||||
sentry_flutter: f1d86adcb93a959bc47a40d8d55059bdf7569bc5
|
sentry_flutter: 090351ce1ff5f96a4b33ef9455b7e3b28185387d
|
||||||
share_plus: 36537c04ce0c3e3f5bd297ce4318b6d5ee5fd6cf
|
share_plus: 36537c04ce0c3e3f5bd297ce4318b6d5ee5fd6cf
|
||||||
shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
|
shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
|
||||||
sqflite: 673a0e54cc04b7d6dba8d24fb8095b31c3a99eec
|
sqflite: 673a0e54cc04b7d6dba8d24fb8095b31c3a99eec
|
||||||
|
Loading…
Reference in New Issue
Block a user