chore: only show emoji button for save-vocab tokens, fix alignment for non-token text (#4071)
This commit is contained in:
parent
d89d852488
commit
26a3a03ad6
2 changed files with 114 additions and 72 deletions
|
|
@ -124,6 +124,7 @@ class HtmlMessage extends StatelessWidget {
|
|||
'tg-forward',
|
||||
// #Pangea
|
||||
'token',
|
||||
'nontoken',
|
||||
// Pangea#
|
||||
};
|
||||
|
||||
|
|
@ -255,6 +256,12 @@ class HtmlMessage extends StatelessWidget {
|
|||
position = substringIndex;
|
||||
}
|
||||
|
||||
for (int i = 0; i < result.length; i++) {
|
||||
if (!result[i].startsWith('<') && !result[i].endsWith('>')) {
|
||||
result[i] = '<nontoken>${result[i]}</nontoken>';
|
||||
}
|
||||
}
|
||||
|
||||
if (pangeaMessageEvent?.textDirection == TextDirection.rtl) {
|
||||
for (int i = 0; i < result.length; i++) {
|
||||
final tag = result[i];
|
||||
|
|
@ -913,48 +920,74 @@ class HtmlMessage extends StatelessWidget {
|
|||
'sub' => const TextStyle(fontFeatures: [FontFeature.subscripts()]),
|
||||
_ => null,
|
||||
};
|
||||
// Pangea#
|
||||
return TextSpan(
|
||||
style: switch (node.localName) {
|
||||
'body' => TextStyle(
|
||||
fontSize: fontSize,
|
||||
color: textColor,
|
||||
return WidgetSpan(
|
||||
alignment: readingAssistanceMode == ReadingAssistanceMode.practiceMode
|
||||
? PlaceholderAlignment.bottom
|
||||
: PlaceholderAlignment.middle,
|
||||
child: Column(
|
||||
children: [
|
||||
if (node.localName == 'nontoken' &&
|
||||
overlayController?.selectedMode == SelectMode.emoji)
|
||||
TokenEmojiButton(
|
||||
token: null,
|
||||
eventId: event.eventId,
|
||||
),
|
||||
RichText(
|
||||
text: TextSpan(
|
||||
style: style,
|
||||
children: _renderWithLineBreaks(
|
||||
node.nodes,
|
||||
context,
|
||||
textStyle.merge(style ?? const TextStyle()),
|
||||
depth: depth,
|
||||
),
|
||||
),
|
||||
),
|
||||
'a' => linkStyle,
|
||||
'strong' => const TextStyle(fontWeight: FontWeight.bold),
|
||||
'em' || 'i' => const TextStyle(fontStyle: FontStyle.italic),
|
||||
'del' ||
|
||||
's' ||
|
||||
'strikethrough' =>
|
||||
const TextStyle(decoration: TextDecoration.lineThrough),
|
||||
'u' => const TextStyle(decoration: TextDecoration.underline),
|
||||
'h1' => TextStyle(fontSize: fontSize * 1.6, height: 2),
|
||||
'h2' => TextStyle(fontSize: fontSize * 1.5, height: 2),
|
||||
'h3' => TextStyle(fontSize: fontSize * 1.4, height: 2),
|
||||
'h4' => TextStyle(fontSize: fontSize * 1.3, height: 1.75),
|
||||
'h5' => TextStyle(fontSize: fontSize * 1.2, height: 1.75),
|
||||
'h6' => TextStyle(fontSize: fontSize * 1.1, height: 1.5),
|
||||
'span' => TextStyle(
|
||||
color: node.attributes['color']?.hexToColor ??
|
||||
node.attributes['data-mx-color']?.hexToColor ??
|
||||
textColor,
|
||||
backgroundColor:
|
||||
node.attributes['data-mx-bg-color']?.hexToColor,
|
||||
),
|
||||
'sup' =>
|
||||
const TextStyle(fontFeatures: [FontFeature.superscripts()]),
|
||||
'sub' => const TextStyle(fontFeatures: [FontFeature.subscripts()]),
|
||||
_ => null,
|
||||
},
|
||||
children: _renderWithLineBreaks(
|
||||
node.nodes,
|
||||
context,
|
||||
// #Pangea
|
||||
textStyle.merge(style ?? const TextStyle()),
|
||||
// Pangea#
|
||||
depth: depth,
|
||||
],
|
||||
),
|
||||
);
|
||||
// return TextSpan(
|
||||
// style: switch (node.localName) {
|
||||
// 'body' => TextStyle(
|
||||
// fontSize: fontSize,
|
||||
// color: textColor,
|
||||
// ),
|
||||
// 'a' => linkStyle,
|
||||
// 'strong' => const TextStyle(fontWeight: FontWeight.bold),
|
||||
// 'em' || 'i' => const TextStyle(fontStyle: FontStyle.italic),
|
||||
// 'del' ||
|
||||
// 's' ||
|
||||
// 'strikethrough' =>
|
||||
// const TextStyle(decoration: TextDecoration.lineThrough),
|
||||
// 'u' => const TextStyle(decoration: TextDecoration.underline),
|
||||
// 'h1' => TextStyle(fontSize: fontSize * 1.6, height: 2),
|
||||
// 'h2' => TextStyle(fontSize: fontSize * 1.5, height: 2),
|
||||
// 'h3' => TextStyle(fontSize: fontSize * 1.4, height: 2),
|
||||
// 'h4' => TextStyle(fontSize: fontSize * 1.3, height: 1.75),
|
||||
// 'h5' => TextStyle(fontSize: fontSize * 1.2, height: 1.75),
|
||||
// 'h6' => TextStyle(fontSize: fontSize * 1.1, height: 1.5),
|
||||
// 'span' => TextStyle(
|
||||
// color: node.attributes['color']?.hexToColor ??
|
||||
// node.attributes['data-mx-color']?.hexToColor ??
|
||||
// textColor,
|
||||
// backgroundColor:
|
||||
// node.attributes['data-mx-bg-color']?.hexToColor,
|
||||
// ),
|
||||
// 'sup' => const TextStyle(
|
||||
// fontFeatures: [FontFeature.superscripts()],
|
||||
// ),
|
||||
// 'sub' => const TextStyle(
|
||||
// fontFeatures: [FontFeature.subscripts()],
|
||||
// ),
|
||||
// _ => null,
|
||||
// },
|
||||
// children: _renderWithLineBreaks(
|
||||
// node.nodes,
|
||||
// context,
|
||||
// depth: depth,
|
||||
// ),
|
||||
// );
|
||||
// Pangea#
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,17 +5,17 @@ import 'package:fluffychat/pangea/events/models/pangea_token_model.dart';
|
|||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
|
||||
class TokenEmojiButton extends StatefulWidget {
|
||||
final PangeaToken token;
|
||||
final PangeaToken? token;
|
||||
final String eventId;
|
||||
final String targetId;
|
||||
final VoidCallback onSelect;
|
||||
final String? targetId;
|
||||
final VoidCallback? onSelect;
|
||||
|
||||
const TokenEmojiButton({
|
||||
super.key,
|
||||
required this.token,
|
||||
required this.eventId,
|
||||
required this.targetId,
|
||||
required this.onSelect,
|
||||
this.targetId,
|
||||
this.onSelect,
|
||||
});
|
||||
|
||||
@override
|
||||
|
|
@ -53,36 +53,45 @@ class TokenEmojiButtonState extends State<TokenEmojiButton>
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final emoji = widget.token.vocabConstructID.userSetEmoji.firstOrNull;
|
||||
final eligible = widget.token?.lemma.saveVocab ?? false;
|
||||
final emoji = widget.token?.vocabConstructID.userSetEmoji.firstOrNull;
|
||||
if (_sizeAnimation != null) {
|
||||
return CompositedTransformTarget(
|
||||
link: MatrixState.pAnyState.layerLinkAndKey(widget.targetId).link,
|
||||
child: AnimatedBuilder(
|
||||
key: MatrixState.pAnyState.layerLinkAndKey(widget.targetId).key,
|
||||
animation: _sizeAnimation!,
|
||||
builder: (context, child) {
|
||||
return Container(
|
||||
height: _sizeAnimation!.value,
|
||||
width: _sizeAnimation!.value,
|
||||
alignment: Alignment.center,
|
||||
child: InkWell(
|
||||
onTap: widget.onSelect,
|
||||
borderRadius: BorderRadius.circular(99.0),
|
||||
child: emoji != null
|
||||
? Text(
|
||||
emoji,
|
||||
style: TextStyle(fontSize: buttonSize - 4.0),
|
||||
)
|
||||
: Icon(
|
||||
Icons.add_reaction_outlined,
|
||||
size: buttonSize - 4.0,
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
final content = AnimatedBuilder(
|
||||
key: widget.targetId != null
|
||||
? MatrixState.pAnyState.layerLinkAndKey(widget.targetId!).key
|
||||
: null,
|
||||
animation: _sizeAnimation!,
|
||||
builder: (context, child) {
|
||||
return Container(
|
||||
height: _sizeAnimation!.value,
|
||||
width: eligible ? _sizeAnimation!.value : 0,
|
||||
alignment: Alignment.center,
|
||||
child: eligible
|
||||
? InkWell(
|
||||
onTap: widget.onSelect,
|
||||
borderRadius: BorderRadius.circular(99.0),
|
||||
child: emoji != null
|
||||
? Text(
|
||||
emoji,
|
||||
style: TextStyle(fontSize: buttonSize - 4.0),
|
||||
)
|
||||
: Icon(
|
||||
Icons.add_reaction_outlined,
|
||||
size: buttonSize - 4.0,
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
),
|
||||
)
|
||||
: null,
|
||||
);
|
||||
},
|
||||
);
|
||||
return widget.targetId != null
|
||||
? CompositedTransformTarget(
|
||||
link:
|
||||
MatrixState.pAnyState.layerLinkAndKey(widget.targetId!).link,
|
||||
child: content,
|
||||
)
|
||||
: content;
|
||||
}
|
||||
|
||||
return const SizedBox.shrink();
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue