mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-24 19:16:44 +08:00
@@ -63,7 +63,7 @@ class VideoCardH extends StatelessWidget {
|
||||
onLongPress: onLongPress ??
|
||||
() => imageSaveDialog(
|
||||
title: videoItem.title,
|
||||
cover: videoItem.pic,
|
||||
cover: videoItem.cover,
|
||||
),
|
||||
onTap: onTap ??
|
||||
() async {
|
||||
@@ -132,7 +132,7 @@ class VideoCardH extends StatelessWidget {
|
||||
clipBehavior: Clip.none,
|
||||
children: [
|
||||
NetworkImgLayer(
|
||||
src: videoItem.pic,
|
||||
src: videoItem.cover,
|
||||
width: maxWidth,
|
||||
height: maxHeight,
|
||||
),
|
||||
@@ -219,21 +219,20 @@ class VideoCardH extends StatelessWidget {
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 2,
|
||||
TextSpan(
|
||||
children: [
|
||||
for (var i in item.titleList!)
|
||||
TextSpan(
|
||||
text: i['text'],
|
||||
style: TextStyle(
|
||||
fontSize: theme.textTheme.bodyMedium!.fontSize,
|
||||
height: 1.42,
|
||||
letterSpacing: 0.3,
|
||||
color: i['type'] == 'em'
|
||||
? theme.colorScheme.primary
|
||||
: theme.colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
children: item.titleList!
|
||||
.map((e) => TextSpan(
|
||||
text: e.text,
|
||||
style: TextStyle(
|
||||
fontSize:
|
||||
theme.textTheme.bodyMedium!.fontSize,
|
||||
height: 1.42,
|
||||
letterSpacing: 0.3,
|
||||
color: e.isEm
|
||||
? theme.colorScheme.primary
|
||||
: theme.colorScheme.onSurface,
|
||||
),
|
||||
))
|
||||
.toList()),
|
||||
),
|
||||
)
|
||||
] else
|
||||
|
||||
@@ -1,242 +0,0 @@
|
||||
import 'package:PiliPlus/common/constants.dart';
|
||||
import 'package:PiliPlus/common/widgets/badge.dart';
|
||||
import 'package:PiliPlus/common/widgets/image/image_save.dart';
|
||||
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
|
||||
import 'package:PiliPlus/common/widgets/progress_bar/video_progress_indicator.dart';
|
||||
import 'package:PiliPlus/common/widgets/stat/stat.dart';
|
||||
import 'package:PiliPlus/common/widgets/video_popup_menu.dart';
|
||||
import 'package:PiliPlus/models/common/badge_type.dart';
|
||||
import 'package:PiliPlus/models/space_archive/item.dart';
|
||||
import 'package:PiliPlus/utils/page_utils.dart';
|
||||
import 'package:PiliPlus/utils/utils.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
|
||||
// 视频卡片 - 水平布局
|
||||
class VideoCardHMemberVideo extends StatelessWidget {
|
||||
const VideoCardHMemberVideo({
|
||||
super.key,
|
||||
required this.videoItem,
|
||||
this.onTap,
|
||||
this.bvid,
|
||||
this.fromViewAid,
|
||||
});
|
||||
final SpaceArchiveItem videoItem;
|
||||
final VoidCallback? onTap;
|
||||
final dynamic bvid;
|
||||
final String? fromViewAid;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
return Stack(
|
||||
clipBehavior: Clip.none,
|
||||
children: [
|
||||
InkWell(
|
||||
onLongPress: () => imageSaveDialog(
|
||||
title: videoItem.title,
|
||||
cover: videoItem.cover,
|
||||
),
|
||||
onTap: onTap ??
|
||||
() async {
|
||||
if (videoItem.isPgc == true &&
|
||||
videoItem.uri?.isNotEmpty == true) {
|
||||
if (PageUtils.viewPgcFromUri(videoItem.uri!)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (videoItem.bvid == null || videoItem.cid == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
PageUtils.toVideoPage(
|
||||
'bvid=${videoItem.bvid}&cid=${videoItem.cid}',
|
||||
arguments: {
|
||||
'heroTag': Utils.makeHeroTag(videoItem.bvid),
|
||||
},
|
||||
);
|
||||
} catch (err) {
|
||||
SmartDialog.showToast(err.toString());
|
||||
}
|
||||
},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: StyleString.safeSpace,
|
||||
vertical: 5,
|
||||
),
|
||||
child: LayoutBuilder(
|
||||
builder: (BuildContext context, BoxConstraints boxConstraints) {
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
AspectRatio(
|
||||
aspectRatio: StyleString.aspectRatio,
|
||||
child: LayoutBuilder(
|
||||
builder: (BuildContext context,
|
||||
BoxConstraints boxConstraints) {
|
||||
final double maxWidth = boxConstraints.maxWidth;
|
||||
final double maxHeight = boxConstraints.maxHeight;
|
||||
return Stack(
|
||||
clipBehavior: Clip.none,
|
||||
children: [
|
||||
NetworkImgLayer(
|
||||
src: videoItem.cover,
|
||||
width: maxWidth,
|
||||
height: maxHeight,
|
||||
),
|
||||
if (fromViewAid == videoItem.param)
|
||||
const Positioned.fill(
|
||||
child: DecoratedBox(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: StyleString.mdRadius,
|
||||
color: Colors.black54,
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
'上次观看',
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 15,
|
||||
letterSpacing: 5,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (videoItem.badges?.isNotEmpty == true)
|
||||
PBadge(
|
||||
text: videoItem.badges!
|
||||
.map((item) => item.text)
|
||||
.join('|'),
|
||||
right: 6.0,
|
||||
top: 6.0,
|
||||
type: videoItem.badges!.first.text == '充电专属'
|
||||
? PBadgeType.error
|
||||
: PBadgeType.primary,
|
||||
),
|
||||
if (videoItem.history != null) ...[
|
||||
Builder(builder: (context) {
|
||||
try {
|
||||
return Positioned(
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
child: videoProgressIndicator(
|
||||
videoItem.history!['progress'] /
|
||||
videoItem.history!['duration'],
|
||||
),
|
||||
);
|
||||
} catch (_) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
}),
|
||||
Builder(builder: (context) {
|
||||
try {
|
||||
return PBadge(
|
||||
text: videoItem.history!['progress'] ==
|
||||
videoItem.history!['duration']
|
||||
? '已看完'
|
||||
: '${Utils.timeFormat(videoItem.history!['progress'])}/${Utils.timeFormat(videoItem.history!['duration'])}',
|
||||
right: 6.0,
|
||||
bottom: 6.0,
|
||||
type: PBadgeType.gray,
|
||||
);
|
||||
} catch (_) {
|
||||
return PBadge(
|
||||
text:
|
||||
Utils.timeFormat(videoItem.duration),
|
||||
right: 6.0,
|
||||
bottom: 6.0,
|
||||
type: PBadgeType.gray,
|
||||
);
|
||||
}
|
||||
}),
|
||||
] else if (videoItem.duration > 0)
|
||||
PBadge(
|
||||
text: Utils.timeFormat(videoItem.duration),
|
||||
right: 6.0,
|
||||
bottom: 6.0,
|
||||
type: PBadgeType.gray,
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
videoContent(context, theme),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
bottom: 0,
|
||||
right: 12,
|
||||
child: VideoPopupMenu(
|
||||
size: 29,
|
||||
iconSize: 17,
|
||||
videoItem: videoItem,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget videoContent(BuildContext context, ThemeData theme) {
|
||||
final isCurr = fromViewAid == videoItem.param ||
|
||||
(videoItem.bvid != null && videoItem.bvid == bvid);
|
||||
return Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
videoItem.title,
|
||||
textAlign: TextAlign.start,
|
||||
style: TextStyle(
|
||||
fontWeight: isCurr ? FontWeight.bold : null,
|
||||
fontSize: theme.textTheme.bodyMedium!.fontSize,
|
||||
height: 1.42,
|
||||
letterSpacing: 0.3,
|
||||
color: isCurr ? theme.colorScheme.primary : null,
|
||||
),
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
videoItem.season != null
|
||||
? Utils.dateFormat(videoItem.season?['mtime'])
|
||||
: videoItem.publishTimeText ?? '',
|
||||
maxLines: 1,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
height: 1,
|
||||
color: theme.colorScheme.outline,
|
||||
overflow: TextOverflow.clip,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 3),
|
||||
Row(
|
||||
children: [
|
||||
StatView(
|
||||
context: context,
|
||||
theme: 'gray',
|
||||
value: videoItem.stat.viewStr,
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
StatDanMu(
|
||||
context: context,
|
||||
theme: 'gray',
|
||||
value: videoItem.stat.danmuStr,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -36,7 +36,7 @@ class VideoCardV extends StatelessWidget {
|
||||
String? goto = videoItem.goto;
|
||||
switch (goto) {
|
||||
case 'bangumi':
|
||||
PageUtils.viewBangumi(epId: videoItem.param!);
|
||||
PageUtils.viewPgc(epId: videoItem.param!);
|
||||
break;
|
||||
case 'av':
|
||||
String bvid = videoItem.bvid ?? IdUtils.av2bv(videoItem.aid!);
|
||||
@@ -47,7 +47,7 @@ class VideoCardV extends StatelessWidget {
|
||||
PageUtils.toVideoPage(
|
||||
'bvid=$bvid&cid=$cid',
|
||||
arguments: {
|
||||
'pic': videoItem.pic,
|
||||
'pic': videoItem.cover,
|
||||
'heroTag': heroTag,
|
||||
},
|
||||
);
|
||||
@@ -106,7 +106,7 @@ class VideoCardV extends StatelessWidget {
|
||||
onTap: () => onPushDetail(Utils.makeHeroTag(videoItem.aid)),
|
||||
onLongPress: () => imageSaveDialog(
|
||||
title: videoItem.title,
|
||||
cover: videoItem.pic,
|
||||
cover: videoItem.cover,
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
@@ -120,7 +120,7 @@ class VideoCardV extends StatelessWidget {
|
||||
clipBehavior: Clip.none,
|
||||
children: [
|
||||
NetworkImgLayer(
|
||||
src: videoItem.pic,
|
||||
src: videoItem.cover,
|
||||
width: maxWidth,
|
||||
height: maxHeight,
|
||||
),
|
||||
@@ -181,7 +181,7 @@ class VideoCardV extends StatelessWidget {
|
||||
children: [
|
||||
if (videoItem.goto == 'bangumi')
|
||||
PBadge(
|
||||
text: videoItem.bangumiBadge,
|
||||
text: videoItem.pgcBadge,
|
||||
isStack: false,
|
||||
size: PBadgeSize.small,
|
||||
type: PBadgeType.line_primary,
|
||||
|
||||
@@ -1,120 +0,0 @@
|
||||
import 'package:PiliPlus/common/constants.dart';
|
||||
import 'package:PiliPlus/common/widgets/badge.dart';
|
||||
import 'package:PiliPlus/common/widgets/image/image_save.dart';
|
||||
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
|
||||
import 'package:PiliPlus/http/search.dart';
|
||||
import 'package:PiliPlus/models/common/badge_type.dart';
|
||||
import 'package:PiliPlus/models/space/item.dart';
|
||||
import 'package:PiliPlus/utils/app_scheme.dart';
|
||||
import 'package:PiliPlus/utils/id_utils.dart';
|
||||
import 'package:PiliPlus/utils/page_utils.dart';
|
||||
import 'package:PiliPlus/utils/utils.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
// 视频卡片 - 垂直布局
|
||||
class VideoCardVMemberHome extends StatelessWidget {
|
||||
final SpaceItem videoItem;
|
||||
|
||||
const VideoCardVMemberHome({
|
||||
super.key,
|
||||
required this.videoItem,
|
||||
});
|
||||
|
||||
Future<void> onPushDetail(heroTag) async {
|
||||
String? goto = videoItem.goto;
|
||||
switch (goto) {
|
||||
case 'bangumi':
|
||||
PageUtils.viewBangumi(epId: videoItem.param);
|
||||
break;
|
||||
case 'av':
|
||||
if (videoItem.isPgc == true && videoItem.uri?.isNotEmpty == true) {
|
||||
if (PageUtils.viewPgcFromUri(videoItem.uri!)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
String? aid = videoItem.param;
|
||||
String? bvid = videoItem.bvid;
|
||||
if (aid == null && bvid == null) {
|
||||
return;
|
||||
}
|
||||
int? cid = videoItem.firstCid;
|
||||
cid ??= await SearchHttp.ab2c(aid: aid, bvid: bvid);
|
||||
PageUtils.toVideoPage(
|
||||
'bvid=${bvid ?? IdUtils.av2bv(int.parse(aid!))}&cid=$cid',
|
||||
arguments: {
|
||||
'pic': videoItem.cover,
|
||||
'heroTag': heroTag,
|
||||
},
|
||||
);
|
||||
break;
|
||||
default:
|
||||
if (videoItem.uri?.isNotEmpty == true) {
|
||||
PiliScheme.routePushFromUrl(videoItem.uri!);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Card(
|
||||
clipBehavior: Clip.hardEdge,
|
||||
margin: EdgeInsets.zero,
|
||||
child: InkWell(
|
||||
onTap: () => onPushDetail(Utils.makeHeroTag(videoItem.bvid)),
|
||||
onLongPress: () => imageSaveDialog(
|
||||
title: videoItem.title,
|
||||
cover: videoItem.cover,
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
AspectRatio(
|
||||
aspectRatio: StyleString.aspectRatio,
|
||||
child: LayoutBuilder(
|
||||
builder: (context, boxConstraints) {
|
||||
double maxWidth = boxConstraints.maxWidth;
|
||||
double maxHeight = boxConstraints.maxHeight;
|
||||
return Stack(
|
||||
clipBehavior: Clip.none,
|
||||
children: [
|
||||
NetworkImgLayer(
|
||||
src: videoItem.cover,
|
||||
width: maxWidth,
|
||||
height: maxHeight,
|
||||
),
|
||||
if ((videoItem.duration ?? -1) > 0)
|
||||
PBadge(
|
||||
bottom: 6,
|
||||
right: 7,
|
||||
size: PBadgeSize.small,
|
||||
type: PBadgeType.gray,
|
||||
text: Utils.timeFormat(videoItem.duration),
|
||||
)
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
videoContent(context, videoItem)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Widget videoContent(BuildContext context, SpaceItem videoItem) {
|
||||
return Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.fromLTRB(6, 5, 6, 5),
|
||||
child: Text(
|
||||
'${videoItem.title}\n',
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: const TextStyle(
|
||||
height: 1.38,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -3,7 +3,7 @@ import 'package:PiliPlus/http/video.dart';
|
||||
import 'package:PiliPlus/models/common/account_type.dart';
|
||||
import 'package:PiliPlus/models/home/rcmd/result.dart';
|
||||
import 'package:PiliPlus/models/model_video.dart';
|
||||
import 'package:PiliPlus/models/space_archive/item.dart';
|
||||
import 'package:PiliPlus/models_new/space/space_archive/item.dart';
|
||||
import 'package:PiliPlus/pages/mine/controller.dart';
|
||||
import 'package:PiliPlus/pages/search/widgets/search_text.dart';
|
||||
import 'package:PiliPlus/utils/storage.dart';
|
||||
|
||||
Reference in New Issue
Block a user