Merge branch 'feature-together'
This commit is contained in:
@ -192,22 +192,15 @@ class VideoHttp {
|
||||
// 视频信息 标题、简介
|
||||
static Future videoIntro({required String bvid}) async {
|
||||
var res = await Request().get(Api.videoIntro, data: {'bvid': bvid});
|
||||
if (res.data['code'] == 0) {
|
||||
VideoDetailResponse result = VideoDetailResponse.fromJson(res.data);
|
||||
if (result.code == 0) {
|
||||
return {'status': true, 'data': result.data!};
|
||||
} else {
|
||||
Map errMap = {
|
||||
-400: '请求错误',
|
||||
-403: '权限不足',
|
||||
-404: '视频资源失效',
|
||||
62002: '稿件不可见',
|
||||
62004: '稿件审核中',
|
||||
};
|
||||
return {
|
||||
'status': false,
|
||||
'data': null,
|
||||
'code': result.code,
|
||||
'msg': errMap[result.code] ?? '请求异常',
|
||||
'code': res.data['code'],
|
||||
'msg': res.data['message'],
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -67,6 +67,7 @@ class VideoDetailData {
|
||||
String? likeIcon;
|
||||
bool? needJumpBv;
|
||||
String? epId;
|
||||
List<Staff>? staff;
|
||||
|
||||
VideoDetailData({
|
||||
this.bvid,
|
||||
@ -103,6 +104,7 @@ class VideoDetailData {
|
||||
this.likeIcon,
|
||||
this.needJumpBv,
|
||||
this.epId,
|
||||
this.staff,
|
||||
});
|
||||
|
||||
VideoDetailData.fromJson(Map<String, dynamic> json) {
|
||||
@ -155,6 +157,9 @@ class VideoDetailData {
|
||||
if (json['redirect_url'] != null) {
|
||||
epId = resolveEpId(json['redirect_url']);
|
||||
}
|
||||
staff = json["staff"] != null
|
||||
? List<Staff>.from(json["staff"]!.map((e) => Staff.fromJson(e)))
|
||||
: null;
|
||||
}
|
||||
|
||||
String resolveEpId(url) {
|
||||
@ -652,3 +657,43 @@ class EpisodeItem {
|
||||
bvid = json['bvid'];
|
||||
}
|
||||
}
|
||||
|
||||
class Staff {
|
||||
Staff({
|
||||
this.mid,
|
||||
this.title,
|
||||
this.name,
|
||||
this.face,
|
||||
this.vip,
|
||||
});
|
||||
|
||||
int? mid;
|
||||
String? title;
|
||||
String? name;
|
||||
String? face;
|
||||
int? status;
|
||||
Vip? vip;
|
||||
|
||||
Staff.fromJson(Map<String, dynamic> json) {
|
||||
mid = json['mid'];
|
||||
title = json['title'];
|
||||
name = json['name'];
|
||||
face = json['face'];
|
||||
vip = Vip.fromJson(json['vip']);
|
||||
}
|
||||
}
|
||||
|
||||
class Vip {
|
||||
Vip({
|
||||
this.type,
|
||||
this.status,
|
||||
});
|
||||
|
||||
int? type;
|
||||
int? status;
|
||||
|
||||
Vip.fromJson(Map<String, dynamic> json) {
|
||||
type = json['type'];
|
||||
status = json['status'];
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ import 'widgets/fav_panel.dart';
|
||||
import 'widgets/intro_detail.dart';
|
||||
import 'widgets/page_panel.dart';
|
||||
import 'widgets/season_panel.dart';
|
||||
import 'widgets/staff_up_item.dart';
|
||||
|
||||
class VideoIntroPanel extends StatefulWidget {
|
||||
final String bvid;
|
||||
@ -409,10 +410,12 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
||||
),
|
||||
)
|
||||
],
|
||||
if (widget.videoDetail!.staff == null)
|
||||
GestureDetector(
|
||||
onTap: onPushMember,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 4),
|
||||
padding:
|
||||
const EdgeInsets.symmetric(vertical: 12, horizontal: 4),
|
||||
child: Row(
|
||||
children: [
|
||||
NetworkImgLayer(
|
||||
@ -434,7 +437,8 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
Obx(() => AnimatedOpacity(
|
||||
Obx(
|
||||
() => AnimatedOpacity(
|
||||
opacity:
|
||||
videoIntroController.followStatus.isEmpty ? 0 : 1,
|
||||
duration: const Duration(milliseconds: 50),
|
||||
@ -474,11 +478,58 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
||||
),
|
||||
),
|
||||
),
|
||||
)),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
if (widget.videoDetail!.staff != null) ...[
|
||||
const SizedBox(height: 15),
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text.rich(
|
||||
TextSpan(
|
||||
style: TextStyle(
|
||||
fontSize:
|
||||
Theme.of(context).textTheme.labelMedium!.fontSize,
|
||||
),
|
||||
children: [
|
||||
TextSpan(
|
||||
text: '创作团队',
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.titleSmall!
|
||||
.copyWith(fontWeight: FontWeight.bold),
|
||||
),
|
||||
const WidgetSpan(child: SizedBox(width: 6)),
|
||||
TextSpan(
|
||||
text: '${widget.videoDetail!.staff!.length}人',
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.outline,
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 120,
|
||||
child: ListView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
children: [
|
||||
for (int i = 0;
|
||||
i < widget.videoDetail!.staff!.length;
|
||||
i++) ...[
|
||||
StaffUpItem(item: widget.videoDetail!.staff![i])
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
]
|
||||
],
|
||||
)),
|
||||
);
|
||||
@ -545,4 +596,8 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
// Widget StaffPanel(BuildContext context, videoIntroController) {
|
||||
// return
|
||||
// }
|
||||
}
|
||||
|
@ -0,0 +1,74 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:pilipala/common/widgets/network_img_layer.dart';
|
||||
import 'package:pilipala/models/video_detail_res.dart';
|
||||
import 'package:pilipala/utils/utils.dart';
|
||||
|
||||
class StaffUpItem extends StatelessWidget {
|
||||
final Staff item;
|
||||
|
||||
const StaffUpItem({
|
||||
super.key,
|
||||
required this.item,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final String heroTag = Utils.makeHeroTag(item.mid);
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const SizedBox(height: 15),
|
||||
GestureDetector(
|
||||
onTap: () => Get.toNamed(
|
||||
'/member?mid=${item.mid}',
|
||||
arguments: {'face': item.face, 'heroTag': heroTag},
|
||||
),
|
||||
child: Hero(
|
||||
tag: heroTag,
|
||||
child: NetworkImgLayer(
|
||||
width: 45,
|
||||
height: 45,
|
||||
src: item.face,
|
||||
type: 'avatar',
|
||||
),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 4),
|
||||
child: SizedBox(
|
||||
width: 85,
|
||||
child: Text(
|
||||
item.name!,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
softWrap: false,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
color: item.vip!.status == 1
|
||||
? const Color.fromARGB(255, 251, 100, 163)
|
||||
: null,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 4),
|
||||
child: SizedBox(
|
||||
width: 85,
|
||||
child: Text(
|
||||
item.title!,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
softWrap: false,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.outline,
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user