feat: emote selection

Signed-off-by: dom <githubaccount56556@proton.me>
This commit is contained in:
dom
2026-07-23 16:13:37 +08:00
parent 565a2f8754
commit 0ca091ac48
12 changed files with 250 additions and 20 deletions

View File

@@ -1,5 +1,6 @@
import 'dart:io';
import 'dart:io' show File, HttpException;
import 'package:PiliPlus/common/style.dart';
import 'package:PiliPlus/common/widgets/button/icon_button.dart';
import 'package:PiliPlus/common/widgets/button/toolbar_icon_button.dart';
import 'package:PiliPlus/common/widgets/flutter/text_field/controller.dart';
@@ -252,8 +253,8 @@ abstract class CommonRichTextPubPageState<T extends CommonRichTextPubPage>
if (emote is e.Emote) {
final isTextEmote = width == null;
onInsertText(
isTextEmote ? emote.text! : '\uFFFC',
RichTextType.emoji,
isTextEmote ? emote.text! : Style.placeHolder,
.emoji,
rawText: emote.text!,
emote: isTextEmote
? null
@@ -265,8 +266,8 @@ abstract class CommonRichTextPubPageState<T extends CommonRichTextPubPage>
);
} else if (emote is Emoticon) {
onInsertText(
'\uFFFC',
RichTextType.emoji,
Style.placeHolder,
.emoji,
rawText: emote.emoji!,
emote: Emote(
url: emote.url!,
@@ -282,13 +283,13 @@ abstract class CommonRichTextPubPageState<T extends CommonRichTextPubPage>
final list = <Map<String, dynamic>>[];
for (final e in editController.items) {
switch (e.type) {
case RichTextType.text || RichTextType.composing || RichTextType.common:
case .text || .composing || .common:
list.add({
"raw_text": e.text,
"type": 1,
"biz_id": "",
});
case RichTextType.at:
case .at:
list
..add({
"raw_text": '@${e.rawText}',
@@ -300,13 +301,13 @@ abstract class CommonRichTextPubPageState<T extends CommonRichTextPubPage>
"type": 1,
"biz_id": "",
});
case RichTextType.emoji:
case .emoji:
list.add({
"raw_text": e.rawText,
"type": 9,
"biz_id": "",
});
case RichTextType.vote:
case .vote:
list
..add({
"raw_text": e.rawText,
@@ -346,7 +347,7 @@ abstract class CommonRichTextPubPageState<T extends CommonRichTextPubPage>
void _onInsertUser(MentionItem e, bool fromClick) {
onInsertText(
'@${e.name} ',
RichTextType.at,
.at,
rawText: e.name,
id: e.uid,
fromClick: fromClick,
@@ -374,7 +375,7 @@ abstract class CommonRichTextPubPageState<T extends CommonRichTextPubPage>
TextEditingDelta delta;
if (selection.isCollapsed) {
if (type == RichTextType.at && fromClick == false) {
if (type == .at && fromClick == false) {
delta = RichTextEditingDeltaReplacement(
oldText: oldValue.text,
replacementText: text,

View File

@@ -1,5 +1,7 @@
// 内容
import 'package:PiliPlus/common/style.dart';
import 'package:PiliPlus/common/widgets/custom_icon.dart';
import 'package:PiliPlus/common/widgets/emote_span.dart';
import 'package:PiliPlus/common/widgets/flutter/text/text.dart' as custom_text;
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/common/widgets/image_grid/image_grid_view.dart';

View File

@@ -1,5 +1,6 @@
import 'dart:io' show Platform;
import 'package:PiliPlus/common/widgets/emote_span.dart';
import 'package:PiliPlus/common/widgets/gesture/tap_gesture_recognizer.dart';
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/common/widgets/image_grid/image_grid_view.dart';
@@ -160,7 +161,8 @@ TextSpan? richNode(
case 'RICH_TEXT_NODE_TYPE_EMOJI' when (i.emoji != null):
final size = i.emoji!.size * 20.0;
spanChildren.add(
WidgetSpan(
EmoteSpan(
rawText: i.origText,
child: NetworkImgLayer(
src: i.emoji!.url,
type: ImageType.emote,

View File

@@ -154,15 +154,14 @@ class _DynamicDetailPageState
try {
for (final e in richTextNodes) {
if (e.type == 'RICH_TEXT_NODE_TYPE_EMOJI') {
const placeHolder = '\uFFFC';
items.add(
RichTextItem(
text: placeHolder,
text: Style.placeHolder,
rawText: e.origText,
type: .emoji,
range: TextRange(
start: buffer.length,
end: buffer.length + placeHolder.length,
end: buffer.length + Style.placeHolder.length,
),
emote: Emote(
url: e.emoji!.url!,
@@ -170,7 +169,7 @@ class _DynamicDetailPageState
),
),
);
buffer.write(placeHolder);
buffer.write(Style.placeHolder);
continue;
}
final range = TextRange(

View File

@@ -7,6 +7,7 @@ import 'package:PiliPlus/common/widgets/badge.dart';
import 'package:PiliPlus/common/widgets/custom_icon.dart';
import 'package:PiliPlus/common/widgets/dialog/dialog.dart';
import 'package:PiliPlus/common/widgets/dialog/report.dart';
import 'package:PiliPlus/common/widgets/emote_span.dart';
import 'package:PiliPlus/common/widgets/flutter/text/text.dart' as custom_text;
import 'package:PiliPlus/common/widgets/gesture/tap_gesture_recognizer.dart';
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';

View File

@@ -4,6 +4,7 @@ import 'dart:math' as math;
import 'package:PiliPlus/common/constants.dart';
import 'package:PiliPlus/common/style.dart';
import 'package:PiliPlus/common/widgets/badge.dart';
import 'package:PiliPlus/common/widgets/emote_span.dart';
import 'package:PiliPlus/common/widgets/gesture/tap_gesture_recognizer.dart';
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/common/widgets/image_viewer/hero.dart';
@@ -689,7 +690,8 @@ class ChatItem extends StatelessWidget {
if (emoji != null) {
final size = emoji['size'];
children.add(
WidgetSpan(
EmoteSpan(
rawText: matchStr,
child: NetworkImgLayer(
width: size,
height: size,