mod: @用户渲染、jumpUrl渲染

This commit is contained in:
guozhigq
2023-04-27 13:54:55 +08:00
parent 0ec926839c
commit 0aba791e2c
3 changed files with 80 additions and 109 deletions

View File

@ -20,7 +20,7 @@ class ReplyContent {
atNameToMid = json['at_name_to_mid'] ?? {}; atNameToMid = json['at_name_to_mid'] ?? {};
memebers = json['memebers'] ?? []; memebers = json['memebers'] ?? [];
emote = json['emote'] ?? {}; emote = json['emote'] ?? {};
jumpUrl = json['jumpUrl'] ?? {}; jumpUrl = json['jump_url'] ?? {};
pictures = json['pictures'] ?? []; pictures = json['pictures'] ?? [];
} }
} }

View File

@ -13,6 +13,6 @@ class ReplyUpper {
mid = json['mid']; mid = json['mid'];
top = json['top'] != null top = json['top'] != null
? ReplyItemModel.fromJson(json['top'], json['mid']) ? ReplyItemModel.fromJson(json['top'], json['mid'])
: ReplyItemModel(); : null;
} }
} }

View File

@ -16,7 +16,7 @@ class ReplyItem extends StatelessWidget {
child: Column( child: Column(
children: [ children: [
Padding( Padding(
padding: const EdgeInsets.fromLTRB(12, 8, 8, 0), padding: const EdgeInsets.fromLTRB(12, 6, 8, 0),
child: content(context), child: content(context),
), ),
Divider( Divider(
@ -31,11 +31,6 @@ class ReplyItem extends StatelessWidget {
Widget lfAvtar(context) { Widget lfAvtar(context) {
return Container( return Container(
margin: const EdgeInsets.only(top: 5), margin: const EdgeInsets.only(top: 5),
clipBehavior: Clip.hardEdge,
decoration: BoxDecoration(
border: Border.all(
color: Theme.of(context).colorScheme.primary.withOpacity(0.03)),
),
child: NetworkImgLayer( child: NetworkImgLayer(
src: replyItem!.member!.avatar, src: replyItem!.member!.avatar,
width: 30, width: 30,
@ -104,7 +99,7 @@ class ReplyItem extends StatelessWidget {
focusNode: FocusNode(), focusNode: FocusNode(),
selectionControls: MaterialTextSelectionControls(), selectionControls: MaterialTextSelectionControls(),
child: Text.rich( child: Text.rich(
style: const TextStyle(height: 1.6), style: const TextStyle(height: 1.65),
TextSpan( TextSpan(
children: [ children: [
buildContent(context, replyItem!.content!), buildContent(context, replyItem!.content!),
@ -301,65 +296,8 @@ InlineSpan buildContent(BuildContext context, content) {
return TextSpan(text: content.message); return TextSpan(text: content.message);
} }
List<InlineSpan> spanChilds = []; List<InlineSpan> spanChilds = [];
// if (content.atNameToMid.isNotEmpty) { // 匹配表情
// print(content.message); String matchEmote = content.message.splitMapJoin(
// content.atNameToMid.forEach((key, value) {
// key = '@' + key;
// int lastIndex = content.message.indexOf(key);
// int endIndex = (lastIndex + key.length).toInt();
// if (lastIndex >= 0) {
// spanChilds.add(TextSpan(
// text: '@' + key,
// style: TextStyle(color: Theme.of(context).colorScheme.primary)));
// content.message = content.message.replaceRange(lastIndex, endIndex, '');
// spanChilds.add(TextSpan(text: content.message));
// }
// spanChilds.add(TextSpan(text: content.message.substring(lastIndex)));
// });
// // return TextSpan(children: spanChilds);
// }
// if (content.emote.isNotEmpty) {
// content.emote.forEach((key, value) {
// int lastIndex = content.message.indexOf(key);
// int endIndex = content.message.indexOf(key) + key.length;
// if (lastIndex >= 0) {
// content.message = content.message.replaceRange(lastIndex, endIndex, '');
// spanChilds.add(TextSpan(text: content.message.substring(0, lastIndex)));
// }
// spanChilds.add(WidgetSpan(
// child: NetworkImgLayer(
// src: value["url"],
// width: 20,
// height: 20,
// )));
// });
// // return TextSpan(children: spanChilds);
// }
// if (content.pictures.isNotEmpty) {
// spanChilds.add(TextSpan(text: content.message));
// spanChilds.add(const WidgetSpan(
// child: SizedBox(
// height: 4,
// )));
// for (var i = 0; i < content.pictures.length; i++) {
// spanChilds.add(
// WidgetSpan(
// child: SizedBox(
// height: 180,
// child: NetworkImgLayer(
// src: content.pictures[i]['img_src'],
// width: 200,
// height: 200 *
// content.pictures[i]['img_height'] /
// content.pictures[i]['img_width'],
// ),
// ),
// ),
// );
// }
// return TextSpan(children: spanChilds);
// }
content.message.splitMapJoin(
RegExp(r"\[.*?\]"), RegExp(r"\[.*?\]"),
onMatch: (Match match) { onMatch: (Match match) {
String matchStr = match[0]!; String matchStr = match[0]!;
@ -379,54 +317,86 @@ InlineSpan buildContent(BuildContext context, content) {
return matchStr; return matchStr;
} }
} }
return matchStr; return '';
}, },
onNonMatch: (String str) { onNonMatch: (String str) {
try { // 匹配@用户
if (content.atNameToMid.isNotEmpty) { String matchMember = str;
return str.splitMapJoin( if (content.atNameToMid.isNotEmpty) {
RegExp(r"@.*:"), matchMember = str.splitMapJoin(
onMatch: (Match match) { RegExp(r"@.*:"),
if (match[0] != null) { onMatch: (Match match) {
content.atNameToMid.forEach((key, value) { if (match[0] != null) {
spanChilds.add( content.atNameToMid.forEach((key, value) {
TextSpan( spanChilds.add(
text: '@$key ', TextSpan(
style: TextStyle( text: '@$key ',
fontSize: style: TextStyle(
Theme.of(context).textTheme.titleSmall!.fontSize, fontSize:
color: Theme.of(context).colorScheme.primary, Theme.of(context).textTheme.titleSmall!.fontSize,
), color: Theme.of(context).colorScheme.primary,
recognizer: TapGestureRecognizer()
..onTap = () => {
print('跳转至用户主页'),
},
), ),
); recognizer: TapGestureRecognizer()
}); ..onTap = () => {
} print('跳转至用户主页'),
return match[0]!; },
}, ),
onNonMatch: (String str) { );
spanChilds.add(TextSpan(text: str)); });
return str; }
}, return '';
); },
} else { onNonMatch: (String str) {
spanChilds.add(TextSpan(text: str)); spanChilds.add(TextSpan(text: str));
return str; return str;
} },
} catch (e) { );
spanChilds.add(TextSpan(text: str)); } else {
return str; matchMember = str;
} }
// 匹配 jumpUrl
String matchUrl = matchMember;
if (content.jumpUrl.isNotEmpty) {
List urlKeys = content.jumpUrl.keys.toList();
matchUrl = matchMember.splitMapJoin(
RegExp("(?:${urlKeys.join("|")})"),
onMatch: (Match match) {
String matchStr = match[0]!;
// spanChilds.add(TextSpan(text: matchStr));
spanChilds.add(
TextSpan(
text: content.jumpUrl[matchStr]['title'],
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
),
recognizer: TapGestureRecognizer()
..onTap = () => {
print('Url 点击'),
},
),
);
return '';
},
onNonMatch: (String str) {
spanChilds.add(TextSpan(text: str));
return str;
},
);
}
if (content.atNameToMid.isEmpty && content.jumpUrl.isEmpty) {
spanChilds.add(TextSpan(text: str));
}
return str;
}, },
); );
// 图片渲染
if (content.pictures.isNotEmpty) { if (content.pictures.isNotEmpty) {
spanChilds.add(const WidgetSpan( spanChilds.add(
child: SizedBox( const TextSpan(text: '\n'),
height: 4, );
)));
for (var i = 0; i < content.pictures.length; i++) { for (var i = 0; i < content.pictures.length; i++) {
spanChilds.add( spanChilds.add(
WidgetSpan( WidgetSpan(
@ -444,5 +414,6 @@ InlineSpan buildContent(BuildContext context, content) {
); );
} }
} }
// spanChilds.add(TextSpan(text: matchMember));
return TextSpan(children: spanChilds); return TextSpan(children: spanChilds);
} }