opt: 首页推荐卡片

This commit is contained in:
guozhigq
2024-04-24 23:56:07 +08:00
parent e699df52e3
commit 72a8c33a66

View File

@ -1,6 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:pilipala/utils/feed_back.dart';
import '../../models/model_rec_video_item.dart'; import '../../models/model_rec_video_item.dart';
import 'overlay_pop.dart'; import 'overlay_pop.dart';
import 'stat/danmu.dart'; import 'stat/danmu.dart';
@ -20,15 +21,11 @@ import 'network_img_layer.dart';
class VideoCardV extends StatelessWidget { class VideoCardV extends StatelessWidget {
final dynamic videoItem; final dynamic videoItem;
final int crossAxisCount; final int crossAxisCount;
// final Function()? longPress;
// final Function()? longPressEnd;
const VideoCardV({ const VideoCardV({
Key? key, Key? key,
required this.videoItem, required this.videoItem,
required this.crossAxisCount, required this.crossAxisCount,
// this.longPress,
// this.longPressEnd,
}) : super(key: key); }) : super(key: key);
bool isStringNumeric(String str) { bool isStringNumeric(String str) {
@ -128,11 +125,7 @@ class VideoCardV extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
String heroTag = Utils.makeHeroTag(videoItem.id); String heroTag = Utils.makeHeroTag(videoItem.id);
return Card( return InkWell(
elevation: 0,
clipBehavior: Clip.hardEdge,
margin: EdgeInsets.zero,
child: InkWell(
onTap: () async => onPushDetail(heroTag), onTap: () async => onPushDetail(heroTag),
onLongPress: () { onLongPress: () {
SmartDialog.show( SmartDialog.show(
@ -142,6 +135,7 @@ class VideoCardV extends StatelessWidget {
), ),
); );
}, },
borderRadius: BorderRadius.circular(16),
child: Column( child: Column(
children: [ children: [
AspectRatio( AspectRatio(
@ -182,7 +176,6 @@ class VideoCardV extends StatelessWidget {
VideoContent(videoItem: videoItem, crossAxisCount: crossAxisCount) VideoContent(videoItem: videoItem, crossAxisCount: crossAxisCount)
], ],
), ),
),
); );
} }
} }
@ -252,11 +245,28 @@ class VideoContent extends StatelessWidget {
const Spacer(), const Spacer(),
], ],
if (videoItem.goto == 'av') if (videoItem.goto == 'av')
VideoPopupMenu( SizedBox(
size: 24, width: 24,
iconSize: 14, height: 24,
videoItem: videoItem, child: IconButton(
onPressed: () {
feedBack();
showModalBottomSheet(
context: context,
useRootNavigator: true,
isScrollControlled: true,
builder: (context) {
return MorePanel(videoItem: videoItem);
},
);
},
icon: Icon(
Icons.more_vert_outlined,
color: Theme.of(context).colorScheme.outline,
size: 14,
), ),
),
)
], ],
), ),
], ],
@ -279,15 +289,9 @@ class VideoStat extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Row( return Row(
children: [ children: [
StatView( StatView(theme: 'gray', view: videoItem.stat.view),
theme: 'gray',
view: videoItem.stat.view,
),
const SizedBox(width: 8), const SizedBox(width: 8),
StatDanMu( StatDanMu(theme: 'gray', danmu: videoItem.stat.danmu),
theme: 'gray',
danmu: videoItem.stat.danmu,
),
if (videoItem is RecVideoItemModel) ...<Widget>[ if (videoItem is RecVideoItemModel) ...<Widget>[
crossAxisCount > 1 ? const Spacer() : const SizedBox(width: 8), crossAxisCount > 1 ? const Spacer() : const SizedBox(width: 8),
RichText( RichText(
@ -306,68 +310,39 @@ class VideoStat extends StatelessWidget {
} }
} }
class VideoPopupMenu extends StatelessWidget { class MorePanel extends StatelessWidget {
final double? size;
final double? iconSize;
final dynamic videoItem; final dynamic videoItem;
const MorePanel({super.key, required this.videoItem});
const VideoPopupMenu({ Future<dynamic> menuActionHandler(String type) async {
Key? key, switch (type) {
required this.size, case 'block':
required this.iconSize, blockUser();
required this.videoItem, break;
}) : super(key: key); case 'watchLater':
var res = await UserHttp.toViewLater(bvid: videoItem.bvid as String);
@override
Widget build(BuildContext context) {
return SizedBox(
width: size,
height: size,
child: PopupMenuButton<String>(
padding: EdgeInsets.zero,
icon: Icon(
Icons.more_vert_outlined,
color: Theme.of(context).colorScheme.outline,
size: iconSize,
),
position: PopupMenuPosition.under,
onSelected: (String type) {},
itemBuilder: (BuildContext context) => <PopupMenuEntry<String>>[
PopupMenuItem<String>(
onTap: () async {
var res =
await UserHttp.toViewLater(bvid: videoItem.bvid as String);
SmartDialog.showToast(res['msg']); SmartDialog.showToast(res['msg']);
}, Get.back();
value: 'pause', break;
height: 40, default:
child: const Row( }
children: [ }
Icon(Icons.watch_later_outlined, size: 16),
SizedBox(width: 6), void blockUser() async {
Text('稍后再看', style: TextStyle(fontSize: 13))
],
),
),
const PopupMenuDivider(),
PopupMenuItem<String>(
onTap: () async {
SmartDialog.show( SmartDialog.show(
useSystem: true, useSystem: true,
animationType: SmartAnimationType.centerFade_otherSlide, animationType: SmartAnimationType.centerFade_otherSlide,
builder: (BuildContext context) { builder: (BuildContext context) {
return AlertDialog( return AlertDialog(
title: const Text('提示'), title: const Text('提示'),
content: Text( content: Text('确定拉黑:${videoItem.owner.name}(${videoItem.owner.mid})?'
'确定拉黑:${videoItem.owner.name}(${videoItem.owner.mid})?'
'\n\n被拉黑的Up可以在隐私设置-黑名单管理中解除'), '\n\n被拉黑的Up可以在隐私设置-黑名单管理中解除'),
actions: [ actions: [
TextButton( TextButton(
onPressed: () => SmartDialog.dismiss(), onPressed: () => SmartDialog.dismiss(),
child: Text( child: Text(
'点错了', '点错了',
style: TextStyle( style: TextStyle(color: Theme.of(context).colorScheme.outline),
color: Theme.of(context).colorScheme.outline),
), ),
), ),
TextButton( TextButton(
@ -386,18 +361,47 @@ class VideoPopupMenu extends StatelessWidget {
); );
}, },
); );
}, }
value: 'pause',
height: 40, @override
child: Row( Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.only(bottom: MediaQuery.of(context).padding.bottom),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [ children: [
const Icon(Icons.block, size: 16), InkWell(
const SizedBox(width: 6), onTap: () => Get.back(),
Text('拉黑:${videoItem.owner.name}', child: Container(
style: const TextStyle(fontSize: 13)) height: 35,
], padding: const EdgeInsets.only(bottom: 2),
child: Center(
child: Container(
width: 32,
height: 3,
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.outline,
borderRadius: const BorderRadius.all(Radius.circular(3))),
), ),
), ),
),
),
ListTile(
onTap: () async => await menuActionHandler('block'),
minLeadingWidth: 0,
leading: const Icon(Icons.block, size: 19),
title: Text(
'拉黑up主 「${videoItem.owner.name}',
style: Theme.of(context).textTheme.titleSmall,
),
),
ListTile(
onTap: () async => await menuActionHandler('watchLater'),
minLeadingWidth: 0,
leading: const Icon(Icons.watch_later_outlined, size: 19),
title:
Text('添加至稍后再看', style: Theme.of(context).textTheme.titleSmall),
),
], ],
), ),
); );