mod: 侧边栏、动态重构,排行改为首页分区,平板、折叠屏、竖屏视频新适配,播放页可隐藏黑边、截图、点踩,弹幕粗细调整,默认关闭后台播放,弹窗接受返回

This commit is contained in:
orz12
2024-05-20 14:46:31 +08:00
parent fd51cddeca
commit 074bf03946
97 changed files with 4105 additions and 2672 deletions

View File

@@ -8,86 +8,79 @@ class VideoCardHSkeleton extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Skeleton(
child: Padding(
padding: const EdgeInsets.fromLTRB(
StyleString.safeSpace, 7, StyleString.safeSpace, 7),
child: LayoutBuilder(
builder: (context, boxConstraints) {
double width =
(boxConstraints.maxWidth - StyleString.cardSpace * 6) / 2;
return SizedBox(
height: width / StyleString.aspectRatio,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
AspectRatio(
aspectRatio: StyleString.aspectRatio,
child: LayoutBuilder(
builder: (context, boxConstraints) {
return Container(
decoration: BoxDecoration(
child: LayoutBuilder(
builder: (context, boxConstraints) {
double width =
(boxConstraints.maxWidth - StyleString.cardSpace * 6) / 2;
return SizedBox(
height: width / StyleString.aspectRatio,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
AspectRatio(
aspectRatio: StyleString.aspectRatio,
child: LayoutBuilder(
builder: (context, boxConstraints) {
return Container(
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.onInverseSurface,
borderRadius:
BorderRadius.circular(StyleString.imgRadius.x),
),
);
},
),
),
// VideoContent(videoItem: videoItem)
Expanded(
child: Padding(
padding: const EdgeInsets.fromLTRB(10, 4, 6, 4),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
color: Theme.of(context).colorScheme.onInverseSurface,
width: 200,
height: 11,
margin: const EdgeInsets.only(bottom: 5),
),
Container(
color: Theme.of(context).colorScheme.onInverseSurface,
width: 150,
height: 13,
),
const Spacer(),
Container(
color: Theme.of(context).colorScheme.onInverseSurface,
width: 100,
height: 13,
margin: const EdgeInsets.only(bottom: 5),
),
Row(
children: [
Container(
color:
Theme.of(context).colorScheme.onInverseSurface,
borderRadius:
BorderRadius.circular(StyleString.imgRadius.x),
width: 40,
height: 13,
margin: const EdgeInsets.only(right: 8),
),
);
},
),
Container(
color:
Theme.of(context).colorScheme.onInverseSurface,
width: 40,
height: 13,
),
],
)
],
),
// VideoContent(videoItem: videoItem)
Expanded(
child: Padding(
padding: const EdgeInsets.fromLTRB(10, 4, 6, 4),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
color: Theme.of(context).colorScheme.onInverseSurface,
width: 200,
height: 11,
margin: const EdgeInsets.only(bottom: 5),
),
Container(
color: Theme.of(context).colorScheme.onInverseSurface,
width: 150,
height: 13,
),
const Spacer(),
Container(
color: Theme.of(context).colorScheme.onInverseSurface,
width: 100,
height: 13,
margin: const EdgeInsets.only(bottom: 5),
),
Row(
children: [
Container(
color: Theme.of(context)
.colorScheme
.onInverseSurface,
width: 40,
height: 13,
margin: const EdgeInsets.only(right: 8),
),
Container(
color: Theme.of(context)
.colorScheme
.onInverseSurface,
width: 40,
height: 13,
),
],
)
],
),
)),
],
),
);
},
),
)),
],
),
);
},
),
);
}

View File

@@ -1,4 +1,7 @@
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../../utils/download.dart';
import '../constants.dart';
import 'network_img_layer.dart';
@@ -11,9 +14,10 @@ class OverlayPop extends StatelessWidget {
@override
Widget build(BuildContext context) {
final double imgWidth = MediaQuery.sizeOf(context).width - 8 * 2;
final double imgWidth = min(Get.height,Get.width) - 8 * 2;
return Container(
margin: const EdgeInsets.symmetric(horizontal: 8),
width: imgWidth,
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.background,
borderRadius: BorderRadius.circular(10.0),
@@ -70,6 +74,7 @@ class OverlayPop extends StatelessWidget {
tooltip: '保存封面图',
onPressed: () async {
await DownloadUtils.downloadImg(
context,
videoItem.pic != null
? videoItem.pic as String
: videoItem.cover as String,

View File

@@ -72,88 +72,73 @@ class VideoCardH extends StatelessWidget {
SmartDialog.showToast(err.toString());
}
},
child: Padding(
padding: const EdgeInsets.fromLTRB(
StyleString.safeSpace, 5, StyleString.safeSpace, 5),
child: LayoutBuilder(
builder:
(BuildContext context, BoxConstraints boxConstraints) {
final double width = (boxConstraints.maxWidth -
StyleString.cardSpace *
6 /
MediaQuery.textScalerOf(context).scale(1.0)) /
2;
return Container(
constraints: const BoxConstraints(minHeight: 88),
height: width / StyleString.aspectRatio,
child: 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(
children: [
Hero(
tag: heroTag,
child: NetworkImgLayer(
src: videoItem.pic as String,
width: maxWidth,
height: maxHeight,
),
),
if (videoItem.duration != 0)
PBadge(
text: Utils.timeFormat(videoItem.duration!),
right: 6.0,
bottom: 6.0,
type: 'gray',
),
if (type != 'video')
PBadge(
text: type,
left: 6.0,
bottom: 6.0,
type: 'primary',
),
// if (videoItem.rcmdReason != null &&
// videoItem.rcmdReason.content != '')
// pBadge(videoItem.rcmdReason.content, context,
// 6.0, 6.0, null, null),
],
);
},
),
),
VideoContent(
videoItem: videoItem,
source: source,
showOwner: showOwner,
showView: showView,
showDanmaku: showDanmaku,
showPubdate: showPubdate,
)
],
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(
children: [
Hero(
tag: heroTag,
child: NetworkImgLayer(
src: videoItem.pic as String,
width: maxWidth,
height: maxHeight,
),
),
if (videoItem.duration != 0)
PBadge(
text: Utils.timeFormat(videoItem.duration!),
right: 6.0,
bottom: 6.0,
type: 'gray',
),
if (type != 'video')
PBadge(
text: type,
left: 6.0,
bottom: 6.0,
type: 'primary',
),
// if (videoItem.rcmdReason != null &&
// videoItem.rcmdReason.content != '')
// pBadge(videoItem.rcmdReason.content, context,
// 6.0, 6.0, null, null),
],
);
},
),
),
);
},
),
VideoContent(
videoItem: videoItem,
source: source,
showOwner: showOwner,
showView: showView,
showDanmaku: showDanmaku,
showPubdate: showPubdate,
)
],
);
},
),
),
)),
if (source == 'normal')
Positioned(
bottom: 1,
bottom: 0,
right: 10,
child: VideoPopupMenu(
size: 30,
iconSize: 16,
size: 29,
iconSize: 17,
videoItem: videoItem,
),
),
@@ -182,6 +167,10 @@ class VideoContent extends StatelessWidget {
@override
Widget build(BuildContext context) {
String pubdate = showPubdate
? Utils.dateFormat(videoItem.pubdate!, formatType: 'day')
: '';
if (pubdate != '') pubdate += ' ';
return Expanded(
child: Padding(
padding: const EdgeInsets.fromLTRB(10, 0, 6, 0),
@@ -247,7 +236,7 @@ class VideoContent extends StatelessWidget {
Expanded(
flex: 0,
child: Text(
"${showPubdate ? Utils.dateFormat(videoItem.pubdate!, formatType: 'day') + ' ' : ''} ${showOwner ? videoItem.owner.name : ''}",
"${pubdate}${showOwner ? videoItem.owner.name : ''}",
maxLines: 1,
style: TextStyle(
fontSize: 11,
@@ -276,7 +265,7 @@ class VideoContent extends StatelessWidget {
if (source == 'normal') const SizedBox(width: 24),
],
),
const SizedBox(height: 2),
const SizedBox(height: 5),
],
),
),

View File

@@ -191,8 +191,8 @@ class VideoCardV extends StatelessWidget {
right: 0,
bottom: 0,
child: VideoPopupMenu(
size: 30,
iconSize: 16,
size: 29,
iconSize: 17,
videoItem: videoItem,
)),
]);
@@ -224,7 +224,8 @@ class VideoContent extends StatelessWidget {
),
],
),
const SizedBox(height: 2),
const Spacer(),
// const SizedBox(height: 2),
VideoStat(
videoItem: videoItem,
),

View File

@@ -1,6 +1,7 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart';
import '../../http/user.dart';
import '../../http/video.dart';
@@ -11,7 +12,7 @@ class VideoPopupMenu extends StatelessWidget {
final double? size;
final double? iconSize;
final dynamic videoItem;
final double menuItemHeight = 50;
final double menuItemHeight = 45;
const VideoPopupMenu({
Key? key,
@@ -53,10 +54,44 @@ class VideoPopupMenu extends StatelessWidget {
),
PopupMenuItem<String>(
onTap: () async {
SmartDialog.show(
useSystem: true,
animationType: SmartAnimationType.centerFade_otherSlide,
builder: (BuildContext context) {
Get.toNamed('/member?mid=${videoItem.owner.mid}', arguments: {
'face': videoItem.owner.face,
'heroTag': '${videoItem.owner.mid}',
});
},
value: 'visit',
height: menuItemHeight,
child: Row(
children: [
const Icon(CupertinoIcons.person, size: 16),
const SizedBox(width: 6),
Text('访问:${videoItem.owner.name}',
style: const TextStyle(fontSize: 13))
],
),
),
// 不感兴趣
PopupMenuItem<String>(
onTap: () async {
// var res = await VideoHttp.dislike(bvid: videoItem.bvid as String);
// SmartDialog.showToast(res['msg']);
SmartDialog.showToast("暂未实现");
},
value: 'dislike',
height: menuItemHeight,
child: const Row(
children: [
Icon(CupertinoIcons.hand_thumbsdown, size: 16),
SizedBox(width: 6),
Text('不感兴趣', style: TextStyle(fontSize: 13))
],
),
),
PopupMenuItem<String>(
onTap: () async {
await showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: const Text('提示'),
content: Text(
@@ -64,7 +99,7 @@ class VideoPopupMenu extends StatelessWidget {
'\n\n被拉黑的Up可以在隐私设置-黑名单管理中解除'),
actions: [
TextButton(
onPressed: () => SmartDialog.dismiss(),
onPressed: () => Get.back(),
child: Text(
'点错了',
style: TextStyle(
@@ -86,7 +121,7 @@ class VideoPopupMenu extends StatelessWidget {
blackMidsList.insert(0, videoItem.owner.mid);
GStrorage.setting
.put(SettingBoxKey.blackMidsList, blackMidsList);
SmartDialog.dismiss();
Get.back();
SmartDialog.showToast(res['msg'] ?? '成功');
},
child: const Text('确认'),