show user medal

Signed-off-by: dom <githubaccount56556@proton.me>
This commit is contained in:
dom
2026-03-22 15:01:30 +08:00
parent fc7fc18b14
commit 2bebf200df
151 changed files with 1435 additions and 1321 deletions

View File

@@ -1,16 +1,17 @@
import 'package:PiliPlus/common/widgets/flutter/refresh_indicator.dart';
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart';
import 'package:PiliPlus/common/widgets/loading_widget/loading_widget.dart';
import 'package:PiliPlus/common/widgets/pendant_avatar.dart';
import 'package:PiliPlus/common/widgets/scroll_physics.dart';
import 'package:PiliPlus/common/widgets/view_sliver_safe_area.dart';
import 'package:PiliPlus/http/loading_state.dart';
import 'package:PiliPlus/models/common/live/live_contribution_rank_type.dart';
import 'package:PiliPlus/models_new/live/live_contribution_rank/item.dart';
import 'package:PiliPlus/models_new/live/live_contribution_rank/medal_info.dart';
import 'package:PiliPlus/pages/live_room/contribution_rank/controller.dart';
import 'package:PiliPlus/pages/member/widget/medal_widget.dart';
import 'package:PiliPlus/utils/extension/scroll_controller_ext.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:flutter/foundation.dart' show kDebugMode;
import 'package:flutter/material.dart';
import 'package:get/get.dart';
@@ -191,6 +192,23 @@ class _Item extends StatelessWidget {
@override
Widget build(BuildContext context) {
late final colorScheme = ColorScheme.of(context);
Widget child = Text(item.name!);
if (item.uinfoMedal case final uinfoMedal?) {
try {
child = Column(
spacing: 4,
crossAxisAlignment: .start,
children: [
child,
MedalWidget.fromMedalInfo(medal: uinfoMedal),
],
);
} catch (e, s) {
if (kDebugMode) {
Utils.reportError(e, s);
}
}
}
return InkWell(
onTap: () => Get.toNamed('/member?mid=${item.uid}'),
child: Padding(
@@ -214,34 +232,13 @@ class _Item extends StatelessWidget {
),
),
),
PendantAvatar(
avatar: item.face,
size: 42,
),
Expanded(
child: Column(
spacing: 3,
crossAxisAlignment: .start,
children: [
Text(item.name!),
Row(
children: [
if (item.medalInfo case MedalInfo(
:final medalName,
:final level,
))
Text(
'$medalName$level',
style: TextStyle(
fontSize: 12,
color: colorScheme.onSurfaceVariant,
),
),
],
),
],
),
NetworkImgLayer(
src: item.face,
width: 42,
height: 42,
type: .avatar,
),
Expanded(child: child),
if (showScore)
Text(
item.score.toString(),

View File

@@ -12,6 +12,7 @@ import 'package:PiliPlus/models/model_owner.dart';
import 'package:PiliPlus/models_new/live/live_danmaku/danmaku_msg.dart';
import 'package:PiliPlus/models_new/live/live_danmaku/live_emote.dart';
import 'package:PiliPlus/models_new/live/live_dm_info/data.dart';
import 'package:PiliPlus/models_new/live/live_medal_wall/uinfo_medal.dart';
import 'package:PiliPlus/models_new/live/live_room_info_h5/data.dart';
import 'package:PiliPlus/models_new/live/live_room_play_info/codec.dart';
import 'package:PiliPlus/models_new/live/live_superchat/item.dart';
@@ -37,6 +38,7 @@ import 'package:PiliPlus/utils/utils.dart';
import 'package:PiliPlus/utils/video_utils.dart';
import 'package:canvas_danmaku/canvas_danmaku.dart';
import 'package:easy_debounce/easy_throttle.dart';
import 'package:flutter/foundation.dart' show kDebugMode;
import 'package:flutter/material.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart';
@@ -335,6 +337,10 @@ class LiveRoomController extends GetxController {
messages.addAll(response);
scrollToBottom();
}
} else {
if (kDebugMode) {
Utils.reportError(res.toString());
}
}
}
@@ -480,6 +486,7 @@ class LiveRoomController extends GetxController {
name: extra['reply_uname'],
);
}
final medal = user['medal'];
addDm(
DanmakuMsg(
name: name,
@@ -490,6 +497,7 @@ class LiveRoomController extends GetxController {
uemote: uemote,
extra: liveExtra,
reply: reply,
medalInfo: medal == null ? null : UinfoMedal.fromJson(medal),
),
DanmakuContentItem(
msg,
@@ -513,27 +521,27 @@ class LiveRoomController extends GetxController {
}
addDm(item);
break;
case 'SUPER_CHAT_MESSAGE_DELETE' when showSuperChat:
if (obj['roomid'] == roomId) {
final ids = obj['data']?['ids'] as List?;
if (ids != null && ids.isNotEmpty) {
if (superChatType == .valid) {
superChatMsg.removeWhere((e) => ids.contains(e.id));
} else {
bool? refresh;
for (final id in ids) {
if (superChatMsg.firstWhereOrNull((e) => e.id == id)
case final item?) {
item.deleted = true;
refresh ??= true;
}
}
if (refresh ?? false) {
superChatMsg.refresh();
}
}
}
}
// case 'SUPER_CHAT_MESSAGE_DELETE' when showSuperChat:
// if (obj['roomid'] == roomId) {
// final ids = obj['data']?['ids'] as List?;
// if (ids != null && ids.isNotEmpty) {
// if (superChatType == .valid) {
// superChatMsg.removeWhere((e) => ids.contains(e.id));
// } else {
// bool? refresh;
// for (final id in ids) {
// if (superChatMsg.firstWhereOrNull((e) => e.id == id)
// case final item?) {
// item.deleted = true;
// refresh ??= true;
// }
// }
// if (refresh ?? false) {
// superChatMsg.refresh();
// }
// }
// }
// }
case 'WATCHED_CHANGE':
watchedShow.value = obj['data']['text_large'];
break;
@@ -544,7 +552,11 @@ class LiveRoomController extends GetxController {
title.value = obj['data']['title'];
break;
}
} catch (_) {}
} catch (e, s) {
if (kDebugMode) {
Utils.reportError(e, s);
}
}
}
final RxInt likeClickTime = 0.obs;

View File

@@ -4,9 +4,13 @@ import 'package:PiliPlus/common/widgets/flutter/selectable_text/selection_area.d
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/member/widget/medal_widget.dart';
import 'package:PiliPlus/utils/image_utils.dart';
import 'package:PiliPlus/utils/page_utils.dart';
import 'package:PiliPlus/utils/platform_utils.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/foundation.dart' show kDebugMode;
import 'package:flutter/material.dart' hide SelectionArea;
import 'package:get/get.dart';
@@ -135,6 +139,31 @@ class _SuperChatCardState extends State<SuperChatCard> {
final bottomColor = Utils.parseColor(item.backgroundBottomColor);
final border = BorderSide(color: bottomColor);
void showMenu(TapUpDetails e) => _showMenu(e.globalPosition, item);
Widget name = Text(
item.userInfo.uname,
maxLines: 1,
overflow: .ellipsis,
style: TextStyle(
color: Utils.parseColor(item.userInfo.nameColor),
),
);
if (item.medalInfo case final medal?) {
try {
name = Row(
spacing: 5,
children: [
Flexible(child: name),
MedalWidget.fromMedalInfo(medal: medal),
],
);
} catch (e, s) {
if (kDebugMode) {
Utils.reportError(e, s);
}
}
}
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
@@ -146,6 +175,13 @@ class _SuperChatCardState extends State<SuperChatCard> {
borderRadius: const .vertical(top: .circular(8)),
color: Utils.parseColor(item.backgroundColor),
border: Border(top: border, left: border, right: border),
image: item.backgroundImage == null
? null
: DecorationImage(
image: CachedNetworkImageProvider(
ImageUtils.safeThumbnailUrl(item.backgroundImage),
),
),
),
padding: const EdgeInsets.all(8),
child: Row(
@@ -162,12 +198,7 @@ class _SuperChatCardState extends State<SuperChatCard> {
mainAxisSize: .min,
crossAxisAlignment: .start,
children: [
Text(
item.userInfo.uname,
style: TextStyle(
color: Utils.parseColor(item.userInfo.nameColor),
),
),
name,
Text(
"${item.price}",
style: TextStyle(

View File

@@ -2,7 +2,8 @@ import 'dart:io';
import 'dart:math';
import 'dart:ui';
import 'package:PiliPlus/common/constants.dart';
import 'package:PiliPlus/common/assets.dart';
import 'package:PiliPlus/common/style.dart';
import 'package:PiliPlus/common/widgets/button/icon_button.dart';
import 'package:PiliPlus/common/widgets/custom_icon.dart';
import 'package:PiliPlus/common/widgets/flutter/page/page_view.dart';
@@ -384,7 +385,7 @@ class _LiveRoomPageState extends State<LiveRoomPage>
);
} else {
child = Image.asset(
'assets/images/live/default_bg.webp',
Assets.livingBackground,
fit: BoxFit.cover,
width: maxWidth,
height: maxHeight,
@@ -417,7 +418,7 @@ class _LiveRoomPageState extends State<LiveRoomPage>
}
Widget _buildPH(bool isFullScreen) {
final height = maxWidth / StyleString.aspectRatio16x9;
final height = maxWidth / Style.aspectRatio16x9;
final videoHeight = isFullScreen ? maxHeight - padding.top : height;
final bottomHeight = maxHeight - padding.top - height - kToolbarHeight;
return Column(

View File

@@ -7,6 +7,7 @@ import 'package:PiliPlus/models_new/live/live_danmaku/danmaku_msg.dart';
import 'package:PiliPlus/models_new/live/live_superchat/item.dart';
import 'package:PiliPlus/pages/live_room/controller.dart';
import 'package:PiliPlus/pages/live_room/superchat/superchat_card.dart';
import 'package:PiliPlus/pages/member/widget/medal_widget.dart';
import 'package:PiliPlus/pages/video/widgets/header_control.dart';
import 'package:PiliPlus/utils/extension/theme_ext.dart';
import 'package:PiliPlus/utils/utils.dart';
@@ -57,6 +58,21 @@ class LiveRoomChatPanel extends StatelessWidget {
itemBuilder: (_, index) {
final item = liveRoomController.messages[index];
if (item is DanmakuMsg) {
WidgetSpan? medal;
if (item.medalInfo case final medalInfo?) {
try {
medal = WidgetSpan(
child: Padding(
padding: const .symmetric(horizontal: 3),
child: MedalWidget.fromMedalInfo(medal: medalInfo),
),
);
} catch (e, s) {
if (kDebugMode) {
Utils.reportError(e, s);
}
}
}
return Align(
alignment: Alignment.centerLeft,
child: Builder(
@@ -76,7 +92,7 @@ class LiveRoomChatPanel extends StatelessWidget {
TextSpan(
children: [
TextSpan(
text: '${item.name}: ',
text: item.name,
style: TextStyle(
color: nameColor,
fontSize: 14,
@@ -91,6 +107,14 @@ class LiveRoomChatPanel extends StatelessWidget {
item,
)),
),
?medal,
TextSpan(
text: ': ',
style: TextStyle(
color: nameColor,
fontSize: 14,
),
),
if (item.reply case final reply?)
TextSpan(
text: '@${reply.name} ',