Compare commits

...

5 Commits

Author SHA1 Message Date
dom
f0050dd6e6 fix pendent offset
Signed-off-by: dom <githubaccount56556@proton.me>
2026-03-29 11:47:58 +08:00
dom
e6a2f65b4e fix reply up badge
Signed-off-by: dom <githubaccount56556@proton.me>
2026-03-29 11:47:58 +08:00
dom
2fc3f9864f opt ui
Signed-off-by: dom <githubaccount56556@proton.me>
2026-03-29 10:51:52 +08:00
dom
64c05a1b06 upgrade deps
Signed-off-by: dom <githubaccount56556@proton.me>
2026-03-29 10:02:00 +08:00
ninatan777
7c4e20f96c safely parse up list (#1876)
* fix: 兼容 mid/roomId/count 字段为字符串或数字类型

* update

---------

Co-authored-by: dom <githubaccount56556@proton.me>
2026-03-29 10:01:10 +08:00
13 changed files with 195 additions and 134 deletions

View File

@@ -0,0 +1,31 @@
import 'package:flutter/rendering.dart' show RenderProxyBox, BoxHitTestResult;
import 'package:flutter/widgets.dart';
class ExtraHitTestWidget extends SingleChildRenderObjectWidget {
const ExtraHitTestWidget({
super.key,
required this.width,
required Widget super.child,
});
final double width;
@override
RenderObject createRenderObject(BuildContext context) {
return RenderExtraHitTestWidget(width: width);
}
}
class RenderExtraHitTestWidget extends RenderProxyBox {
RenderExtraHitTestWidget({
required double width,
}) : _width = width;
final double _width;
@override
bool hitTestChildren(BoxHitTestResult result, {required Offset position}) {
return super.hitTestChildren(result, position: position) ||
position.dx <= _width;
}
}

View File

@@ -57,7 +57,7 @@ class PendantAvatar extends StatelessWidget {
final pendantSize = size * 1.75;
pendant = Positioned(
// -(size * 1.75 - size) / 2
top: -0.375 * size + pendentOffset,
top: -0.375 * size + pendentOffset / 2,
child: IgnorePointer(
child: NetworkImgLayer(
type: .emote,

View File

@@ -1,3 +1,5 @@
import 'package:PiliPlus/utils/utils.dart';
class FollowUpModel {
FollowUpModel({
this.liveUsers,
@@ -49,7 +51,7 @@ class LiveUsers {
List<LiveUserItem>? items;
LiveUsers.fromJson(Map<String, dynamic> json) {
count = json['count'] ?? 0;
count = Utils.safeToInt(json['count']) ?? 0;
group = json['group'];
items = (json['items'] as List?)
?.map<LiveUserItem>((e) => LiveUserItem.fromJson(e))
@@ -63,14 +65,11 @@ class LiveUserItem extends UpItem {
int? roomId;
String? title;
LiveUserItem.fromJson(Map<String, dynamic> json)
: super(mid: json['mid'] ?? 0) {
face = json['face'];
LiveUserItem.fromJson(Map<String, dynamic> json) : super.fromJson(json) {
isReserveRecall = json['is_reserve_recall'];
jumpUrl = json['jump_url'];
roomId = json['room_id'];
roomId = Utils.safeToInt(json['room_id']);
title = json['title'];
uname = json['uname'];
}
}
@@ -90,7 +89,7 @@ class UpItem {
UpItem.fromJson(Map<String, dynamic> json) {
face = json['face'];
hasUpdate = json['has_update'];
mid = json['mid'] ?? 0;
mid = Utils.safeToInt(json['mid']) ?? 0;
uname = json['uname'];
}

View File

@@ -53,7 +53,7 @@ class SuperChatItem {
'ts': 0,
'uinfo': {
'medal': {
"name": "MedalName",
"name": "Medal",
"level": Utils.random.nextInt(40),
"id": 123,
"ruid": 456,

View File

@@ -188,6 +188,7 @@ abstract class CommonDynPageState<T extends StatefulWidget> extends State<T>
isVideoDetail: !showBackBtn,
replyType: controller.replyType,
firstFloor: replyItem,
upMid: controller.upMid,
),
);
if (showBackBtn) {

View File

@@ -3,6 +3,7 @@ import 'dart:math';
import 'package:PiliPlus/common/assets.dart';
import 'package:PiliPlus/common/style.dart';
import 'package:PiliPlus/common/widgets/dialog/report.dart';
import 'package:PiliPlus/common/widgets/extra_hit_test_widget.dart';
import 'package:PiliPlus/common/widgets/pendant_avatar.dart';
import 'package:PiliPlus/http/constants.dart';
import 'package:PiliPlus/http/loading_state.dart';
@@ -98,37 +99,40 @@ class AuthorPanel extends StatelessWidget {
Get.toNamed('/member?mid=${moduleAuthor.mid}');
}
: null,
child: Row(
spacing: 10,
children: [
PendantAvatar(
size: 40,
moduleAuthor.face,
pendantImage: moduleAuthor.pendant?.image,
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
moduleAuthor.name!,
maxLines: 1,
overflow: .ellipsis,
style: TextStyle(
color:
moduleAuthor.vip != null &&
moduleAuthor.vip!.status > 0 &&
moduleAuthor.vip!.type == 2
? theme.colorScheme.vipColor
: theme.colorScheme.onSurface,
fontSize: theme.textTheme.titleSmall!.fontSize,
),
),
?pubTs,
],
child: ExtraHitTestWidget(
width: 50,
child: Row(
spacing: 10,
children: [
PendantAvatar(
size: 40,
moduleAuthor.face,
pendantImage: moduleAuthor.pendant?.image,
),
),
],
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
moduleAuthor.name!,
maxLines: 1,
overflow: .ellipsis,
style: TextStyle(
color:
moduleAuthor.vip != null &&
moduleAuthor.vip!.status > 0 &&
moduleAuthor.vip!.type == 2
? theme.colorScheme.vipColor
: theme.colorScheme.onSurface,
fontSize: theme.textTheme.titleSmall!.fontSize,
),
),
?pubTs,
],
),
),
],
),
),
);
Widget? moreBtn = isSave

View File

@@ -153,11 +153,11 @@ class _SuperChatCardState extends State<SuperChatCard> {
name = Row(
spacing: 5,
children: [
Flexible(child: name),
MedalWidget.fromMedalInfo(
medal: medal,
padding: MedalWidget.mediumPadding,
),
Flexible(child: name),
],
);
} catch (e, s) {

View File

@@ -239,6 +239,7 @@ class _MainReplyPageState extends State<MainReplyPage>
isVideoDetail: false,
replyType: _controller.replyType,
firstFloor: replyItem,
upMid: _controller.upMid,
),
).constraintWidth(),
),

View File

@@ -250,6 +250,7 @@ class _VideoReplyPanelState extends State<VideoReplyPanel>
replyType: _videoReplyController.videoType.replyType,
isVideoDetail: true,
isNested: widget.isNested,
upMid: _videoReplyController.upMid,
),
);
});

View File

@@ -5,6 +5,7 @@ import 'package:PiliPlus/common/constants.dart';
import 'package:PiliPlus/common/style.dart';
import 'package:PiliPlus/common/widgets/badge.dart';
import 'package:PiliPlus/common/widgets/dialog/report.dart';
import 'package:PiliPlus/common/widgets/extra_hit_test_widget.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';
@@ -139,100 +140,108 @@ class ReplyItemGrpc extends StatelessWidget {
feedBack();
Get.toNamed('/member?mid=${replyItem.mid}');
},
child: Row(
crossAxisAlignment: .center,
spacing: 12,
children: [
PendantAvatar(
member.face,
size: 34,
badgeSize: 14,
vipStatus: member.vipStatus.toInt(),
officialType: member.officialVerifyType.toInt(),
pendantImage: member.hasGarbPendantImage()
? member.garbPendantImage
: null,
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Row(
spacing: 6,
children: [
Flexible(
child: Text(
member.name,
maxLines: 1,
overflow: .ellipsis,
style: TextStyle(
color: (member.vipStatus > 0 && member.vipType == 2)
? theme.colorScheme.vipColor
: theme.colorScheme.outline,
fontSize: 13,
child: ExtraHitTestWidget(
width: 46,
child: Row(
crossAxisAlignment: .center,
spacing: 12,
children: [
PendantAvatar(
member.face,
size: 34,
badgeSize: 14,
vipStatus: member.vipStatus.toInt(),
officialType: member.officialVerifyType.toInt(),
pendantImage: member.hasGarbPendantImage()
? member.garbPendantImage
: null,
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Row(
spacing: 6,
children: [
Flexible(
child: Text(
member.name,
maxLines: 1,
overflow: .ellipsis,
style: TextStyle(
color: (member.vipStatus > 0 && member.vipType == 2)
? theme.colorScheme.vipColor
: theme.colorScheme.outline,
fontSize: 13,
),
),
),
),
Image.asset(
Utils.levelName(
member.level,
isSeniorMember: member.isSeniorMember == 1,
),
height: 11,
cacheHeight: 11.cacheSize(context),
),
if (replyItem.mid == upMid)
const PBadge(
text: 'UP',
size: PBadgeSize.small,
isStack: false,
fontSize: 9,
)
else if (GlobalData().showMedal &&
member.hasFansMedalLevel())
MedalWidget(
medalName: member.fansMedalName,
level: member.fansMedalLevel.toInt(),
backgroundColor: DmUtils.decimalToColor(
member.fansMedalColor.toInt(),
Image.asset(
Utils.levelName(
member.level,
isSeniorMember: member.isSeniorMember == 1,
),
nameColor: DmUtils.decimalToColor(
member.fansMedalColorName.toInt(),
height: 11,
cacheHeight: 11.cacheSize(context),
),
if (replyItem.mid == upMid)
const PBadge(
text: 'UP',
size: PBadgeSize.small,
isStack: false,
fontSize: 9,
)
else if (GlobalData().showMedal &&
member.hasFansMedalLevel())
MedalWidget(
medalName: member.fansMedalName,
level: member.fansMedalLevel.toInt(),
backgroundColor: DmUtils.decimalToColor(
member.fansMedalColor.toInt(),
),
nameColor: DmUtils.decimalToColor(
member.fansMedalColorName.toInt(),
),
padding: const .symmetric(
horizontal: 6,
vertical: 1.5,
),
),
padding: const .symmetric(horizontal: 6, vertical: 1.5),
),
],
),
Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(
replyLevel == 0
? DateFormatUtils.format(
replyItem.ctime.toInt(),
format: DateFormatUtils.longFormatDs,
)
: DateFormatUtils.dateFormat(replyItem.ctime.toInt()),
style: TextStyle(
fontSize: theme.textTheme.labelSmall!.fontSize,
color: theme.colorScheme.outline,
),
),
if (replyItem.replyControl.hasLocation())
],
),
Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(
'${replyItem.replyControl.location}',
replyLevel == 0
? DateFormatUtils.format(
replyItem.ctime.toInt(),
format: DateFormatUtils.longFormatDs,
)
: DateFormatUtils.dateFormat(
replyItem.ctime.toInt(),
),
style: TextStyle(
fontSize: theme.textTheme.labelSmall!.fontSize,
color: theme.colorScheme.outline,
),
),
],
),
],
if (replyItem.replyControl.hasLocation())
Text(
'${replyItem.replyControl.location}',
style: TextStyle(
fontSize: theme.textTheme.labelSmall!.fontSize,
color: theme.colorScheme.outline,
),
),
],
),
],
),
),
),
],
],
),
),
);
if (PendantAvatar.showDecorate) {

View File

@@ -16,6 +16,7 @@ import 'package:PiliPlus/utils/extension/widget_ext.dart';
import 'package:PiliPlus/utils/num_utils.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart';
import 'package:fixnum/fixnum.dart' show Int64;
import 'package:flutter/material.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart';
@@ -33,6 +34,7 @@ class VideoReplyReplyPanel extends CommonSlidePage {
required this.isVideoDetail,
required this.replyType,
this.isNested = false,
this.upMid,
});
final int? id;
final int oid;
@@ -42,6 +44,7 @@ class VideoReplyReplyPanel extends CommonSlidePage {
final bool isVideoDetail;
final int replyType;
final bool isNested;
final Int64? upMid;
@override
State<VideoReplyReplyPanel> createState() => _VideoReplyReplyPanelState();
@@ -224,7 +227,7 @@ class _VideoReplyReplyPanelState extends State<VideoReplyReplyPanel>
replyLevel: 2,
needDivider: false,
onReply: (replyItem) => _controller.onReply(replyItem, index: -1),
upMid: _controller.upMid,
upMid: widget.upMid ?? _controller.upMid,
onCheckReply: (item) =>
_controller.onCheckReply(item, isManual: true),
),

View File

@@ -1154,12 +1154,13 @@ packages:
source: git
version: "1.3.7"
media_kit_libs_ios_video:
dependency: transitive
dependency: "direct overridden"
description:
name: media_kit_libs_ios_video
sha256: b5382994eb37a4564c368386c154ad70ba0cc78dacdd3fb0cd9f30db6d837991
url: "https://pub.dev"
source: hosted
path: "libs/ios/media_kit_libs_ios_video"
ref: dev
resolved-ref: "547999bfb8b5cae9f9aca6125f46fd7cb500e994"
url: "https://github.com/bggRGjQaUbCoE/media-kit.git"
source: git
version: "1.1.4"
media_kit_libs_linux:
dependency: transitive
@@ -1170,12 +1171,13 @@ packages:
source: hosted
version: "1.2.1"
media_kit_libs_macos_video:
dependency: transitive
dependency: "direct overridden"
description:
name: media_kit_libs_macos_video
sha256: f26aa1452b665df288e360393758f84b911f70ffb3878032e1aabba23aa1032d
url: "https://pub.dev"
source: hosted
path: "libs/macos/media_kit_libs_macos_video"
ref: dev
resolved-ref: "547999bfb8b5cae9f9aca6125f46fd7cb500e994"
url: "https://github.com/bggRGjQaUbCoE/media-kit.git"
source: git
version: "1.1.4"
media_kit_libs_video:
dependency: "direct main"

View File

@@ -281,6 +281,16 @@ dependency_overrides:
url: https://github.com/My-Responsitories/media-kit.git
path: libs/windows/media_kit_libs_windows_video
ref: version_1.2.5
media_kit_libs_ios_video:
git:
url: https://github.com/bggRGjQaUbCoE/media-kit.git
path: libs/ios/media_kit_libs_ios_video
ref: dev
media_kit_libs_macos_video:
git:
url: https://github.com/bggRGjQaUbCoE/media-kit.git
path: libs/macos/media_kit_libs_macos_video
ref: dev
font_awesome_flutter: 10.9.0
dev_dependencies: