report sc

Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
bggRGjQaUbCoE
2026-01-03 15:44:37 +08:00
parent 2b5f111fb1
commit fd06fa9cc4
19 changed files with 678 additions and 397 deletions

View File

@@ -3,7 +3,7 @@ import 'dart:async';
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/models/common/image_type.dart';
import 'package:PiliPlus/models_new/live/live_superchat/item.dart';
import 'package:PiliPlus/pages/video/introduction/ugc/widgets/selectable_text.dart';
import 'package:PiliPlus/utils/platform_utils.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
@@ -12,13 +12,15 @@ class SuperChatCard extends StatefulWidget {
const SuperChatCard({
super.key,
required this.item,
required this.onRemove,
this.onRemove,
this.persistentSC = false,
required this.onReport,
});
final SuperChatItem item;
final VoidCallback onRemove;
final VoidCallback? onRemove;
final bool persistentSC;
final VoidCallback onReport;
@override
State<SuperChatCard> createState() => _SuperChatCardState();
@@ -40,7 +42,7 @@ class _SuperChatCardState extends State<SuperChatCard> {
final offset = widget.item.endTime - now;
if (offset > 0) {
_remains = offset.obs;
_timer = Timer.periodic(const Duration(seconds: 1), _callback);
_startTimer();
} else {
_remove();
}
@@ -56,7 +58,7 @@ class _SuperChatCardState extends State<SuperChatCard> {
void _onRemove() {
widget
..item.expired = true
..onRemove();
..onRemove?.call();
}
void _callback(_) {
@@ -69,6 +71,10 @@ class _SuperChatCardState extends State<SuperChatCard> {
}
}
void _startTimer() {
_timer = Timer.periodic(const Duration(seconds: 1), _callback);
}
void _cancelTimer() {
_timer?.cancel();
_timer = null;
@@ -80,61 +86,101 @@ class _SuperChatCardState extends State<SuperChatCard> {
super.dispose();
}
void _showMenu(Offset offset, SuperChatItem item) {
final flag = _timer != null;
if (flag) {
_cancelTimer();
}
showMenu(
context: context,
position: RelativeRect.fromLTRB(offset.dx, offset.dy, offset.dx, 0),
items: [
PopupMenuItem(
height: 38,
onTap: () => Get.toNamed('/member?mid=${item.uid}'),
child: Text(
'访问: ${item.userInfo.uname}',
style: const TextStyle(fontSize: 13),
),
),
PopupMenuItem(
height: 38,
onTap: widget.onReport,
child: const Text(
'举报',
style: TextStyle(fontSize: 13),
),
),
],
).whenComplete(() {
if (flag && mounted) {
_startTimer();
}
});
}
@override
Widget build(BuildContext context) {
final item = widget.item;
final bottomColor = Utils.parseColor(item.backgroundBottomColor);
final border = BorderSide(color: bottomColor);
void showMenu(TapUpDetails e) => _showMenu(e.globalPosition, item);
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Container(
decoration: BoxDecoration(
borderRadius: const BorderRadius.vertical(top: Radius.circular(8)),
color: Utils.parseColor(item.backgroundColor),
border: Border(top: border, left: border, right: border),
),
padding: const EdgeInsets.all(8),
child: Row(
spacing: 12,
children: [
GestureDetector(
onTap: () => Get.toNamed('/member?mid=${item.uid}'),
child: NetworkImgLayer(
GestureDetector(
onTapUp: showMenu,
onSecondaryTapUp: PlatformUtils.isDesktop ? showMenu : null,
child: Container(
decoration: BoxDecoration(
borderRadius: const BorderRadius.vertical(
top: Radius.circular(8),
),
color: Utils.parseColor(item.backgroundColor),
border: Border(top: border, left: border, right: border),
),
padding: const EdgeInsets.all(8),
child: Row(
spacing: 12,
children: [
NetworkImgLayer(
src: item.userInfo.face,
width: 45,
height: 45,
type: ImageType.avatar,
),
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
item.userInfo.uname,
style: TextStyle(
color: Utils.parseColor(item.userInfo.nameColor),
Expanded(
child: Column(
mainAxisSize: .min,
crossAxisAlignment: .start,
children: [
Text(
item.userInfo.uname,
style: TextStyle(
color: Utils.parseColor(item.userInfo.nameColor),
),
),
),
Text(
"${item.price}",
style: TextStyle(
color: Utils.parseColor(item.backgroundPriceColor),
Text(
"${item.price}",
style: TextStyle(
color: Utils.parseColor(item.backgroundPriceColor),
),
),
),
],
),
),
if (_remains != null)
Obx(
() => Text(
_remains.toString(),
style: const TextStyle(fontSize: 14, color: Colors.grey),
],
),
),
],
if (_remains != null)
Obx(
() => Text(
_remains.toString(),
style: const TextStyle(
fontSize: 14,
color: Colors.grey,
),
),
),
],
),
),
),
Container(
@@ -145,9 +191,11 @@ class _SuperChatCardState extends State<SuperChatCard> {
color: bottomColor,
),
padding: const EdgeInsets.all(8),
child: selectableText(
item.message,
style: TextStyle(color: Utils.parseColor(item.messageFontColor)),
child: SelectionArea(
child: Text(
item.message,
style: TextStyle(color: Utils.parseColor(item.messageFontColor)),
),
),
),
],

View File

@@ -3,7 +3,7 @@ import 'package:PiliPlus/pages/live_room/controller.dart';
import 'package:PiliPlus/pages/live_room/superchat/superchat_card.dart';
import 'package:PiliPlus/pages/search/controller.dart';
import 'package:flutter/material.dart';
import 'package:get/get_state_manager/get_state_manager.dart';
import 'package:get/get_state_manager/src/rx_flutter/rx_obx_widget.dart';
class SuperChatPanel extends StatefulWidget {
const SuperChatPanel({
@@ -48,9 +48,10 @@ class _SuperChatPanelState extends DebounceStreamState<SuperChatPanel, bool>
item: item,
onRemove: () => ctr?.add(true),
persistentSC: persistentSC,
onReport: () => widget.controller.reportSC(item),
);
},
separatorBuilder: (_, _) => const SizedBox(height: 12),
separatorBuilder: (_, _) => const SizedBox(height: 8),
),
);
}