Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
bggRGjQaUbCoE
2025-06-05 18:55:07 +08:00
parent 707d2f4b07
commit b149ee4998
39 changed files with 472 additions and 535 deletions

View File

@@ -1,92 +1,48 @@
import 'package:PiliPlus/models/common/stat_type.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:flutter/material.dart';
abstract class _StatItemBase extends StatelessWidget {
final BuildContext context;
final Object value;
final String? theme;
class StatWidget extends StatelessWidget {
final StatType type;
final dynamic value;
final Color? textColor;
final double iconSize;
const _StatItemBase({
required this.context,
const StatWidget({
super.key,
required this.type,
required this.value,
this.theme,
this.textColor,
this.iconSize = 13,
});
IconData get iconData;
String get semanticsLabel;
Color get color {
return textColor ??
switch (theme) {
'gray' =>
Theme.of(context).colorScheme.outline.withValues(alpha: 0.8),
'black' =>
Theme.of(context).colorScheme.onSurface.withValues(alpha: 0.7),
_ => Colors.white,
};
}
@override
Widget build(BuildContext context) {
IconData iconData = switch (type) {
StatType.view => Icons.remove_red_eye_outlined,
StatType.danmaku => Icons.subtitles_outlined,
StatType.like => Icons.thumb_up_outlined,
StatType.reply => Icons.comment_outlined,
StatType.follow => Icons.favorite_border,
StatType.play => Icons.play_circle_outlined,
};
Color color = textColor ??
Theme.of(context).colorScheme.outline.withValues(alpha: 0.8);
return Row(
spacing: 2,
children: [
Icon(
iconData,
size: iconSize,
color: color,
),
const SizedBox(width: 2),
Text(
Utils.numFormat(value),
style: TextStyle(fontSize: 12, color: color),
overflow: TextOverflow.clip,
semanticsLabel: semanticsLabel,
)
),
],
);
}
}
class StatView extends _StatItemBase {
final String? goto;
const StatView({
required super.context,
required super.value,
this.goto,
super.theme,
super.textColor,
}) : super(iconSize: 13);
@override
IconData get iconData => switch (goto) {
'picture' => Icons.remove_red_eye_outlined,
'like' => Icons.thumb_up_outlined,
'reply' => Icons.comment_outlined,
'follow' => Icons.favorite_border,
_ => Icons.play_circle_outlined,
};
@override
String get semanticsLabel =>
'${Utils.numFormat(value)}${goto == "picture" ? "浏览" : "播放"}';
}
class StatDanMu extends _StatItemBase {
const StatDanMu({
required super.context,
required super.value,
super.theme,
super.textColor,
}) : super(iconSize: 14);
@override
IconData get iconData => Icons.subtitles_outlined;
@override
String get semanticsLabel => '${Utils.numFormat(value)}条弹幕';
}

View File

@@ -7,6 +7,7 @@ import 'package:PiliPlus/common/widgets/stat/stat.dart';
import 'package:PiliPlus/common/widgets/video_popup_menu.dart';
import 'package:PiliPlus/http/search.dart';
import 'package:PiliPlus/models/common/badge_type.dart';
import 'package:PiliPlus/models/common/stat_type.dart';
import 'package:PiliPlus/models/model_hot_video_item.dart';
import 'package:PiliPlus/models/model_video.dart';
import 'package:PiliPlus/models/search/result.dart';
@@ -257,16 +258,14 @@ class VideoCardH extends StatelessWidget {
spacing: 8,
children: [
if (showView)
StatView(
context: context,
theme: 'gray',
value: videoItem.stat.viewStr,
StatWidget(
type: StatType.view,
value: videoItem.stat.view,
),
if (showDanmaku)
StatDanMu(
context: context,
theme: 'gray',
value: videoItem.stat.danmuStr,
StatWidget(
type: StatType.danmaku,
value: videoItem.stat.danmu,
),
],
),

View File

@@ -6,6 +6,7 @@ import 'package:PiliPlus/common/widgets/stat/stat.dart';
import 'package:PiliPlus/common/widgets/video_popup_menu.dart';
import 'package:PiliPlus/http/search.dart';
import 'package:PiliPlus/models/common/badge_type.dart';
import 'package:PiliPlus/models/common/stat_type.dart';
import 'package:PiliPlus/models/home/rcmd/result.dart';
import 'package:PiliPlus/models/model_rec_video_item.dart';
import 'package:PiliPlus/utils/app_scheme.dart';
@@ -234,19 +235,17 @@ class VideoCardV extends StatelessWidget {
Widget videoStat(BuildContext context, ThemeData theme) {
return Row(
children: [
StatView(
context: context,
theme: 'gray',
value: videoItem.stat.viewStr,
goto: videoItem.goto,
StatWidget(
value: videoItem.stat.view,
type: StatType.view,
),
const SizedBox(width: 4),
if (videoItem.goto != 'picture')
StatDanMu(
context: context,
theme: 'gray',
value: videoItem.stat.danmuStr,
if (videoItem.goto != 'picture') ...[
const SizedBox(width: 4),
StatWidget(
type: StatType.danmaku,
value: videoItem.stat.danmu,
),
],
if (videoItem is RecVideoItemModel) ...[
const Spacer(),
Text.rich(