From 9578f948b4163cfbbf8f5db5c01d39bfc9bef9da Mon Sep 17 00:00:00 2001 From: dom Date: Mon, 23 Mar 2026 11:47:56 +0800 Subject: [PATCH] tweaks Signed-off-by: dom --- lib/common/widgets/pendant_avatar.dart | 82 +++++++++++-------- lib/models/dynamics/result.dart | 2 +- .../live/live_danmaku/danmaku_msg.dart | 6 +- .../live/live_medal_wall/uinfo_medal.dart | 9 ++ lib/models_new/live/live_superchat/item.dart | 14 +++- lib/pages/article/widgets/opus_content.dart | 4 +- .../live_room/contribution_rank/view.dart | 5 +- lib/pages/live_room/controller.dart | 6 +- .../live_room/superchat/superchat_card.dart | 5 +- lib/pages/live_room/widgets/chat_panel.dart | 27 ++---- lib/pages/member/widget/medal_wall.dart | 4 +- lib/pages/member/widget/medal_widget.dart | 2 + lib/pages/member/widget/user_info_card.dart | 2 +- lib/pages/search_panel/user/widgets/item.dart | 2 + lib/pages/setting/models/extra_settings.dart | 12 ++- .../video/reply/widgets/reply_item_grpc.dart | 6 +- lib/utils/extension/theme_ext.dart | 9 +- lib/utils/global_data.dart | 2 + lib/utils/storage_key.dart | 3 +- lib/utils/storage_pref.dart | 7 +- 20 files changed, 132 insertions(+), 77 deletions(-) diff --git a/lib/common/widgets/pendant_avatar.dart b/lib/common/widgets/pendant_avatar.dart index 437b5be8b..c578e4c13 100644 --- a/lib/common/widgets/pendant_avatar.dart +++ b/lib/common/widgets/pendant_avatar.dart @@ -1,4 +1,5 @@ import 'package:PiliPlus/common/assets.dart'; +import 'package:PiliPlus/common/style.dart'; import 'package:PiliPlus/common/widgets/image/network_img_layer.dart'; import 'package:PiliPlus/models/common/avatar_badge_type.dart'; import 'package:PiliPlus/models/common/image_type.dart'; @@ -18,6 +19,8 @@ class PendantAvatar extends StatelessWidget { this.pendantImage, this.pendentOffset = 6, this.roomId, + this.liveBottom, + this.liveFontSize, this.onTap, }) : preferredSize = size, badgeSize = badgeSize ?? size / 3, @@ -31,7 +34,7 @@ class PendantAvatar extends StatelessWidget { ? .institution : .none; - static bool showDynDecorate = Pref.showDynDecorate; + static bool showDecorate = Pref.showDecorate; final BadgeType badgeType; final String? url; @@ -40,12 +43,14 @@ class PendantAvatar extends StatelessWidget { final String? pendantImage; final double pendentOffset; final int? roomId; + final double? liveBottom; + final double? liveFontSize; final VoidCallback? onTap; @override Widget build(BuildContext context) { final colorScheme = Theme.of(context).colorScheme; - final showPendant = showDynDecorate && pendantImage?.isNotEmpty == true; + final showPendant = showDecorate && pendantImage?.isNotEmpty == true; final size = showPendant ? preferredSize - pendentOffset : preferredSize; Widget? pendant; if (showPendant) { @@ -84,39 +89,8 @@ class PendantAvatar extends StatelessWidget { avatar, ?pendant, if (roomId != null) - Positioned( - bottom: 0, - child: InkWell( - onTap: () => PageUtils.toLiveRoom(roomId), - child: Container( - padding: const EdgeInsets.symmetric(horizontal: 5, vertical: 1), - decoration: BoxDecoration( - color: colorScheme.secondaryContainer, - borderRadius: const BorderRadius.all(Radius.circular(36)), - ), - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - Icon( - size: 16, - applyTextScaling: true, - Icons.equalizer_rounded, - color: colorScheme.onSecondaryContainer, - ), - Text( - '直播中', - style: TextStyle( - height: 1, - fontSize: 13, - color: colorScheme.onSecondaryContainer, - ), - ), - ], - ), - ), - ), - ) - else if (badgeType != BadgeType.none) + _buildLive(colorScheme) + else if (badgeType != .none) _buildBadge(context, colorScheme), ], ); @@ -129,9 +103,45 @@ class PendantAvatar extends StatelessWidget { return child; } + Widget _buildLive(ColorScheme colorScheme) { + final fontSize = liveFontSize ?? 13.0; + return Positioned( + bottom: liveBottom ?? 0.0, + child: GestureDetector( + onTap: () => PageUtils.toLiveRoom(roomId), + child: Container( + padding: const .symmetric(horizontal: 5, vertical: 1), + decoration: BoxDecoration( + color: colorScheme.secondaryContainer, + borderRadius: Style.mdRadius, + ), + child: Row( + mainAxisSize: .min, + children: [ + Icon( + size: fontSize + 3, + applyTextScaling: true, + Icons.equalizer_rounded, + color: colorScheme.onSecondaryContainer, + ), + Text( + '直播中', + style: TextStyle( + height: 1, + fontSize: fontSize, + color: colorScheme.onSecondaryContainer, + ), + ), + ], + ), + ), + ), + ); + } + Widget _buildBadge(BuildContext context, ColorScheme colorScheme) { final child = switch (badgeType) { - BadgeType.vip => Image.asset( + .vip => Image.asset( Assets.vipIcon, width: badgeSize, height: badgeSize, diff --git a/lib/models/dynamics/result.dart b/lib/models/dynamics/result.dart index cc29abd36..4aff0b96d 100644 --- a/lib/models/dynamics/result.dart +++ b/lib/models/dynamics/result.dart @@ -424,7 +424,7 @@ class ModuleAuthorModel extends Avatar { pubTime = json['pub_time']; pubTs = json['pub_ts'] == 0 ? null : Utils.safeToInt(json['pub_ts']); type = json['type']; - if (PendantAvatar.showDynDecorate) { + if (PendantAvatar.showDecorate) { decorate = json['decorate'] == null ? null : Decorate.fromJson(json['decorate']); diff --git a/lib/models_new/live/live_danmaku/danmaku_msg.dart b/lib/models_new/live/live_danmaku/danmaku_msg.dart index c35939f65..2d6af8677 100644 --- a/lib/models_new/live/live_danmaku/danmaku_msg.dart +++ b/lib/models_new/live/live_danmaku/danmaku_msg.dart @@ -2,6 +2,7 @@ import 'package:PiliPlus/models/model_owner.dart'; import 'package:PiliPlus/models_new/live/live_danmaku/live_emote.dart'; import 'package:PiliPlus/models_new/live/live_medal_wall/uinfo_medal.dart'; import 'package:PiliPlus/pages/danmaku/danmaku_model.dart'; +import 'package:PiliPlus/utils/global_data.dart'; class DanmakuMsg { final String name; @@ -55,7 +56,9 @@ class DanmakuMsg { ts: checkInfo['ts'], ct: checkInfo['ct'], ), - medalInfo: medal == null ? null : UinfoMedal.fromJson(medal), + medalInfo: !GlobalData().showMedal || medal == null + ? null + : UinfoMedal.fromJson(medal), ); } @@ -66,5 +69,6 @@ class DanmakuMsg { 'uemote': ?uemote?.toJson(), 'reply': ?reply?.toJson(), 'extra': extra.toJson(), + 'medal': ?medalInfo?.toJson(), }; } diff --git a/lib/models_new/live/live_medal_wall/uinfo_medal.dart b/lib/models_new/live/live_medal_wall/uinfo_medal.dart index 2814599f3..28014acef 100644 --- a/lib/models_new/live/live_medal_wall/uinfo_medal.dart +++ b/lib/models_new/live/live_medal_wall/uinfo_medal.dart @@ -23,4 +23,13 @@ class UinfoMedal { v2MedalColorStart: json['v2_medal_color_start'] as String?, v2MedalColorText: json['v2_medal_color_text'] as String?, ); + + Map toJson() => { + 'name': name, + 'level': level, + 'id': id, + 'ruid': ruid, + 'v2_medal_color_start': v2MedalColorStart, + 'v2_medal_color_text': v2MedalColorText, + }; } diff --git a/lib/models_new/live/live_superchat/item.dart b/lib/models_new/live/live_superchat/item.dart index f73b6d688..8ebb78a9c 100644 --- a/lib/models_new/live/live_superchat/item.dart +++ b/lib/models_new/live/live_superchat/item.dart @@ -1,5 +1,6 @@ import 'package:PiliPlus/models_new/live/live_medal_wall/uinfo_medal.dart'; import 'package:PiliPlus/models_new/live/live_superchat/user_info.dart'; +import 'package:PiliPlus/utils/global_data.dart'; import 'package:PiliPlus/utils/parse_string.dart'; import 'package:PiliPlus/utils/utils.dart'; @@ -50,6 +51,16 @@ class SuperChatItem { }, 'token': '', 'ts': 0, + 'uinfo': { + 'medal': { + "name": "MedalName", + "level": Utils.random.nextInt(40), + "id": 123, + "ruid": 456, + "v2_medal_color_start": "#4C7DFF99", + "v2_medal_color_text": "#FFFFFF", + }, + }, }); factory SuperChatItem.fromJson(Map json) => SuperChatItem( @@ -66,7 +77,7 @@ class SuperChatItem { token: json['token'], ts: Utils.safeToInt(json['ts'])!, userInfo: UserInfo.fromJson(json['user_info'] as Map), - medalInfo: json['uinfo']?['medal'] == null + medalInfo: !GlobalData().showMedal || json['uinfo']?['medal'] == null ? null : UinfoMedal.fromJson(json['uinfo']['medal']), ); @@ -119,5 +130,6 @@ class SuperChatItem { 'token': token, 'ts': ts, 'user_info': userInfo.toJson(), + 'medal': ?medalInfo?.toJson(), }; } diff --git a/lib/pages/article/widgets/opus_content.dart b/lib/pages/article/widgets/opus_content.dart index 18682bb3f..3426070c6 100644 --- a/lib/pages/article/widgets/opus_content.dart +++ b/lib/pages/article/widgets/opus_content.dart @@ -758,9 +758,7 @@ Widget moduleBlockedItem( padding: padding, tapTargetSize: MaterialTapTargetSize.shrinkWrap, visualDensity: visualDensity, - backgroundColor: isDarkMode - ? const Color(0xFF8F0030) - : const Color(0xFFFF6699), + backgroundColor: theme.colorScheme.btnColor, foregroundColor: Colors.white, shape: shape, ), diff --git a/lib/pages/live_room/contribution_rank/view.dart b/lib/pages/live_room/contribution_rank/view.dart index cb7852f57..b29e6d144 100644 --- a/lib/pages/live_room/contribution_rank/view.dart +++ b/lib/pages/live_room/contribution_rank/view.dart @@ -200,7 +200,10 @@ class _Item extends StatelessWidget { crossAxisAlignment: .start, children: [ child, - MedalWidget.fromMedalInfo(medal: uinfoMedal), + MedalWidget.fromMedalInfo( + medal: uinfoMedal, + padding: MedalWidget.mediumPadding, + ), ], ); } catch (e, s) { diff --git a/lib/pages/live_room/controller.dart b/lib/pages/live_room/controller.dart index ac56493a2..ca822d042 100644 --- a/lib/pages/live_room/controller.dart +++ b/lib/pages/live_room/controller.dart @@ -31,6 +31,7 @@ import 'package:PiliPlus/utils/danmaku_utils.dart'; import 'package:PiliPlus/utils/duration_utils.dart'; import 'package:PiliPlus/utils/extension/iterable_ext.dart'; import 'package:PiliPlus/utils/extension/size_ext.dart'; +import 'package:PiliPlus/utils/global_data.dart'; import 'package:PiliPlus/utils/num_utils.dart'; import 'package:PiliPlus/utils/platform_utils.dart'; import 'package:PiliPlus/utils/storage_pref.dart'; @@ -486,7 +487,6 @@ class LiveRoomController extends GetxController { name: extra['reply_uname'], ); } - final medal = user['medal']; addDm( DanmakuMsg( name: name, @@ -497,7 +497,9 @@ class LiveRoomController extends GetxController { uemote: uemote, extra: liveExtra, reply: reply, - medalInfo: medal == null ? null : UinfoMedal.fromJson(medal), + medalInfo: !GlobalData().showMedal || user['medal'] == null + ? null + : UinfoMedal.fromJson(user['medal']), ), DanmakuContentItem( msg, diff --git a/lib/pages/live_room/superchat/superchat_card.dart b/lib/pages/live_room/superchat/superchat_card.dart index 7153a400d..c70ea0a29 100644 --- a/lib/pages/live_room/superchat/superchat_card.dart +++ b/lib/pages/live_room/superchat/superchat_card.dart @@ -154,7 +154,10 @@ class _SuperChatCardState extends State { spacing: 5, children: [ Flexible(child: name), - MedalWidget.fromMedalInfo(medal: medal), + MedalWidget.fromMedalInfo( + medal: medal, + padding: MedalWidget.mediumPadding, + ), ], ); } catch (e, s) { diff --git a/lib/pages/live_room/widgets/chat_panel.dart b/lib/pages/live_room/widgets/chat_panel.dart index 595a0716a..06f17bcb4 100644 --- a/lib/pages/live_room/widgets/chat_panel.dart +++ b/lib/pages/live_room/widgets/chat_panel.dart @@ -63,8 +63,11 @@ class LiveRoomChatPanel extends StatelessWidget { try { medal = WidgetSpan( child: Padding( - padding: const .symmetric(horizontal: 3), - child: MedalWidget.fromMedalInfo(medal: medalInfo), + padding: const .only(right: 4), + child: MedalWidget.fromMedalInfo( + medal: medalInfo, + padding: MedalWidget.mediumPadding, + ), ), ); } catch (e, s) { @@ -78,21 +81,17 @@ class LiveRoomChatPanel extends StatelessWidget { child: Builder( builder: (itemContext) { return Container( - padding: const EdgeInsets.symmetric( - horizontal: 10, - vertical: 4, - ), + padding: const .symmetric(horizontal: 10, vertical: 4), decoration: BoxDecoration( color: bg, - borderRadius: const BorderRadius.all( - Radius.circular(14), - ), + borderRadius: const .all(.circular(14)), ), child: Text.rich( TextSpan( children: [ + ?medal, TextSpan( - text: item.name, + text: '${item.name}: ', style: TextStyle( color: nameColor, fontSize: 14, @@ -107,14 +106,6 @@ class LiveRoomChatPanel extends StatelessWidget { item, )), ), - ?medal, - TextSpan( - text: ': ', - style: TextStyle( - color: nameColor, - fontSize: 14, - ), - ), if (item.reply case final reply?) TextSpan( text: '@${reply.name} ', diff --git a/lib/pages/member/widget/medal_wall.dart b/lib/pages/member/widget/medal_wall.dart index 1e7fe6094..3a0fcfafc 100644 --- a/lib/pages/member/widget/medal_wall.dart +++ b/lib/pages/member/widget/medal_wall.dart @@ -124,9 +124,7 @@ class MedalWall extends StatelessWidget { padding: const .symmetric(horizontal: 8, vertical: 3), decoration: BoxDecoration( borderRadius: const .all(.circular(3)), - color: colorScheme.isDark - ? const Color(0xFF8F0030) - : const Color(0xFFFF6699), + color: colorScheme.btnColor, ), child: const Text( '佩戴中', diff --git a/lib/pages/member/widget/medal_widget.dart b/lib/pages/member/widget/medal_widget.dart index 8fec03bb1..532179262 100644 --- a/lib/pages/member/widget/medal_widget.dart +++ b/lib/pages/member/widget/medal_widget.dart @@ -38,6 +38,8 @@ class MedalWidget extends StatelessWidget { final StrutStyle strutStyle; final EdgeInsets padding; + static const mediumPadding = EdgeInsets.symmetric(horizontal: 6, vertical: 3); + @override Widget build(BuildContext context) { return Container( diff --git a/lib/pages/member/widget/user_info_card.dart b/lib/pages/member/widget/user_info_card.dart index df949170a..79b6be4da 100644 --- a/lib/pages/member/widget/user_info_card.dart +++ b/lib/pages/member/widget/user_info_card.dart @@ -200,7 +200,7 @@ class UserInfoCard extends StatelessWidget { ), if (card.vip?.status == 1) Container( - padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 3), + padding: const .symmetric(horizontal: 8, vertical: 3), decoration: BoxDecoration( borderRadius: Style.mdRadius, color: colorScheme.vipColor, diff --git a/lib/pages/search_panel/user/widgets/item.dart b/lib/pages/search_panel/user/widgets/item.dart index 434bde6cc..e109e8532 100644 --- a/lib/pages/search_panel/user/widgets/item.dart +++ b/lib/pages/search_panel/user/widgets/item.dart @@ -32,6 +32,8 @@ class SearchUserItem extends StatelessWidget { item.upic, size: 42, officialType: item.officialVerify?.type, + liveBottom: -5, + liveFontSize: 11, roomId: item.isLive == 1 ? item.roomId : null, ), const SizedBox(width: 10), diff --git a/lib/pages/setting/models/extra_settings.dart b/lib/pages/setting/models/extra_settings.dart index a241825bc..4e8753aba 100644 --- a/lib/pages/setting/models/extra_settings.dart +++ b/lib/pages/setting/models/extra_settings.dart @@ -32,6 +32,7 @@ import 'package:PiliPlus/utils/accounts.dart'; import 'package:PiliPlus/utils/cache_manager.dart'; import 'package:PiliPlus/utils/extension/num_ext.dart'; import 'package:PiliPlus/utils/feed_back.dart'; +import 'package:PiliPlus/utils/global_data.dart'; import 'package:PiliPlus/utils/image_utils.dart'; import 'package:PiliPlus/utils/path_utils.dart'; import 'package:PiliPlus/utils/platform_utils.dart'; @@ -329,9 +330,16 @@ List get extraSettings => [ SwitchModel( title: '展示头像/评论/动态装饰', leading: const Icon(MdiIcons.stickerCircleOutline), - setKey: SettingBoxKey.showDynDecorate, + setKey: SettingBoxKey.showDecorate, defaultVal: true, - onChanged: (value) => PendantAvatar.showDynDecorate = value, + onChanged: (value) => PendantAvatar.showDecorate = value, + ), + SwitchModel( + title: '显示粉丝勋章', + leading: const Icon(MdiIcons.medalOutline), + setKey: SettingBoxKey.showMedal, + defaultVal: true, + onChanged: (value) => GlobalData().showMedal = value, ), SwitchModel( title: '预览 Live Photo', diff --git a/lib/pages/video/reply/widgets/reply_item_grpc.dart b/lib/pages/video/reply/widgets/reply_item_grpc.dart index bba134983..dcaf39419 100644 --- a/lib/pages/video/reply/widgets/reply_item_grpc.dart +++ b/lib/pages/video/reply/widgets/reply_item_grpc.dart @@ -30,6 +30,7 @@ import 'package:PiliPlus/utils/extension/context_ext.dart'; import 'package:PiliPlus/utils/extension/num_ext.dart'; import 'package:PiliPlus/utils/extension/theme_ext.dart'; import 'package:PiliPlus/utils/feed_back.dart'; +import 'package:PiliPlus/utils/global_data.dart'; import 'package:PiliPlus/utils/image_utils.dart'; import 'package:PiliPlus/utils/page_utils.dart'; import 'package:PiliPlus/utils/platform_utils.dart'; @@ -188,7 +189,8 @@ class ReplyItemGrpc extends StatelessWidget { isStack: false, fontSize: 9, ) - else if (member.hasFansMedalLevel()) + else if (GlobalData().showMedal && + member.hasFansMedalLevel()) MedalWidget( medalName: member.fansMedalName, level: member.fansMedalLevel.toInt(), @@ -233,7 +235,7 @@ class ReplyItemGrpc extends StatelessWidget { ], ), ); - if (PendantAvatar.showDynDecorate) { + if (PendantAvatar.showDecorate) { final garb = replyItem.memberV2.garb; if (garb.hasCardImage()) { const double height = 38.0; diff --git a/lib/utils/extension/theme_ext.dart b/lib/utils/extension/theme_ext.dart index a14f669aa..3f3151a78 100644 --- a/lib/utils/extension/theme_ext.dart +++ b/lib/utils/extension/theme_ext.dart @@ -1,9 +1,14 @@ import 'package:flex_seed_scheme/flex_seed_scheme.dart'; import 'package:flutter/material.dart'; +const _pinkLight = Color(0xFFFF6699); +const _pinkDark = Color(0xFFD44E7D); + extension ColorSchemeExt on ColorScheme { - Color get vipColor => - brightness.isLight ? const Color(0xFFFF6699) : const Color(0xFFD44E7D); + Color get vipColor => brightness.isLight ? _pinkLight : _pinkDark; + + Color get btnColor => + brightness.isLight ? _pinkLight : const Color(0xFF8F0030); Color get freeColor => brightness.isLight ? const Color(0xFFFF7F24) : const Color(0xFFD66011); diff --git a/lib/utils/global_data.dart b/lib/utils/global_data.dart index d536170f6..ff75d45c7 100644 --- a/lib/utils/global_data.dart +++ b/lib/utils/global_data.dart @@ -15,6 +15,8 @@ class GlobalData { bool dynamicsWaterfallFlow = Pref.dynamicsWaterfallFlow; + bool showMedal = Pref.showMedal; + // 私有构造函数 GlobalData._(); diff --git a/lib/utils/storage_key.dart b/lib/utils/storage_key.dart index 20cdd7620..ae90cea50 100644 --- a/lib/utils/storage_key.dart +++ b/lib/utils/storage_key.dart @@ -100,7 +100,8 @@ abstract final class SettingBoxKey { preInitPlayer = 'preInitPlayer', mainTabBarView = 'mainTabBarView', searchSuggestion = 'searchSuggestion', - showDynDecorate = 'showDynDecorate', + showDecorate = 'showDynDecorate', + showMedal = 'showMedal', enableLivePhoto = 'enableLivePhoto', showSeekPreview = 'showSeekPreview', showDmChart = 'showDmChart', diff --git a/lib/utils/storage_pref.dart b/lib/utils/storage_pref.dart index 5bdc570f5..9d8dfec4b 100644 --- a/lib/utils/storage_pref.dart +++ b/lib/utils/storage_pref.dart @@ -477,8 +477,11 @@ abstract final class Pref { static bool get searchSuggestion => _setting.get(SettingBoxKey.searchSuggestion, defaultValue: true); - static bool get showDynDecorate => - _setting.get(SettingBoxKey.showDynDecorate, defaultValue: true); + static bool get showDecorate => + _setting.get(SettingBoxKey.showDecorate, defaultValue: true); + + static bool get showMedal => + _setting.get(SettingBoxKey.showMedal, defaultValue: true); static bool get enableLivePhoto => _setting.get(SettingBoxKey.enableLivePhoto, defaultValue: true);