Merge branch 'design' into alpha
This commit is contained in:
@ -89,20 +89,19 @@ class BangumiInfo extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _BangumiInfoState extends State<BangumiInfo> {
|
class _BangumiInfoState extends State<BangumiInfo> {
|
||||||
late BangumiInfoModel? bangumiItem;
|
String heroTag = Get.arguments['heroTag'];
|
||||||
final BangumiIntroController bangumiIntroController =
|
late final BangumiIntroController bangumiIntroController;
|
||||||
Get.put(BangumiIntroController(), tag: Get.arguments['heroTag']);
|
late final VideoDetailController videoDetailCtr;
|
||||||
|
|
||||||
late VideoDetailController? videoDetailCtr;
|
|
||||||
Box localCache = GStrorage.localCache;
|
Box localCache = GStrorage.localCache;
|
||||||
|
late final BangumiInfoModel? bangumiItem;
|
||||||
late double sheetHeight;
|
late double sheetHeight;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
bangumiIntroController = Get.put(BangumiIntroController(), tag: heroTag);
|
||||||
|
videoDetailCtr = Get.find<VideoDetailController>(tag: heroTag);
|
||||||
bangumiItem = bangumiIntroController.bangumiItem;
|
bangumiItem = bangumiIntroController.bangumiItem;
|
||||||
videoDetailCtr =
|
|
||||||
Get.find<VideoDetailController>(tag: Get.arguments['heroTag']);
|
|
||||||
sheetHeight = localCache.get('sheetHeight');
|
sheetHeight = localCache.get('sheetHeight');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -40,7 +40,7 @@ class _UpPanelState extends State<UpPanel> {
|
|||||||
1,
|
1,
|
||||||
UpItem(
|
UpItem(
|
||||||
face: user.get(UserBoxKey.userFace),
|
face: user.get(UserBoxKey.userFace),
|
||||||
uname: '我的',
|
uname: '我',
|
||||||
mid: user.get(UserBoxKey.userMid),
|
mid: user.get(UserBoxKey.userMid),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@ -62,7 +62,6 @@ class _VideoIntroPanelState extends State<VideoIntroPanel>
|
|||||||
if (snapshot.connectionState == ConnectionState.done) {
|
if (snapshot.connectionState == ConnectionState.done) {
|
||||||
if (snapshot.data['status']) {
|
if (snapshot.data['status']) {
|
||||||
// 请求成功
|
// 请求成功
|
||||||
// return _buildView(context, false, videoDetail);
|
|
||||||
return Obx(
|
return Obx(
|
||||||
() => VideoInfo(
|
() => VideoInfo(
|
||||||
loadingStatus: false,
|
loadingStatus: false,
|
||||||
@ -95,22 +94,48 @@ class VideoInfo extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
||||||
Map videoItem = Get.put(VideoIntroController()).videoItem!;
|
final String heroTag = Get.arguments['heroTag'];
|
||||||
final VideoIntroController videoIntroController =
|
late final VideoIntroController videoIntroController;
|
||||||
Get.put(VideoIntroController(), tag: Get.arguments['heroTag']);
|
late final VideoDetailController videoDetailCtr;
|
||||||
bool isExpand = false;
|
late final Map<dynamic, dynamic> videoItem;
|
||||||
|
|
||||||
late VideoDetailController? videoDetailCtr;
|
|
||||||
Box localCache = GStrorage.localCache;
|
Box localCache = GStrorage.localCache;
|
||||||
late double sheetHeight;
|
late double sheetHeight;
|
||||||
|
|
||||||
|
late final bool loadingStatus; // 加载状态
|
||||||
|
late final int viewCount; // 观看
|
||||||
|
late final int danmakuCount; // 弹幕
|
||||||
|
late final String pubDate; // 发布日期
|
||||||
|
|
||||||
|
late final owner;
|
||||||
|
late final follower;
|
||||||
|
late final followStatus;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
|
||||||
videoDetailCtr =
|
videoIntroController = Get.put(VideoIntroController(), tag: heroTag);
|
||||||
Get.find<VideoDetailController>(tag: Get.arguments['heroTag']);
|
videoDetailCtr = Get.find<VideoDetailController>(tag: heroTag);
|
||||||
|
videoItem = videoIntroController.videoItem!;
|
||||||
sheetHeight = localCache.get('sheetHeight');
|
sheetHeight = localCache.get('sheetHeight');
|
||||||
|
|
||||||
|
loadingStatus = widget.loadingStatus;
|
||||||
|
viewCount = !loadingStatus
|
||||||
|
? widget.videoDetail!.stat!.view
|
||||||
|
: videoItem['stat'].view;
|
||||||
|
danmakuCount = !loadingStatus
|
||||||
|
? widget.videoDetail!.stat!.danmaku
|
||||||
|
: videoItem['stat'].danmaku;
|
||||||
|
pubDate = Utils.dateFormat(
|
||||||
|
!loadingStatus ? widget.videoDetail!.pubdate : videoItem['pubdate'],
|
||||||
|
formatType: 'detail');
|
||||||
|
|
||||||
|
owner = loadingStatus ? videoItem['owner'] : widget.videoDetail!.owner;
|
||||||
|
follower = loadingStatus
|
||||||
|
? '-'
|
||||||
|
: Utils.numFormat(videoIntroController.userStat['follower']);
|
||||||
|
followStatus = videoIntroController.followStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 收藏
|
// 收藏
|
||||||
@ -141,24 +166,39 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 用户主页
|
||||||
|
onPushMember() {
|
||||||
|
feedBack();
|
||||||
|
int mid = !loadingStatus
|
||||||
|
? widget.videoDetail!.owner!.mid
|
||||||
|
: videoItem['owner'].mid;
|
||||||
|
String face = !loadingStatus
|
||||||
|
? widget.videoDetail!.owner!.face
|
||||||
|
: videoItem['owner'].face;
|
||||||
|
Get.toNamed('/member?mid=$mid',
|
||||||
|
arguments: {'face': face, 'heroTag': (mid + 99).toString()});
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
ThemeData t = Theme.of(context);
|
ThemeData t = Theme.of(context);
|
||||||
|
Color outline = t.colorScheme.outline;
|
||||||
return SliverPadding(
|
return SliverPadding(
|
||||||
padding: const EdgeInsets.only(
|
padding: const EdgeInsets.only(
|
||||||
left: StyleString.safeSpace, right: StyleString.safeSpace, top: 10),
|
left: StyleString.safeSpace, right: StyleString.safeSpace, top: 10),
|
||||||
sliver: SliverToBoxAdapter(
|
sliver: SliverToBoxAdapter(
|
||||||
child: !widget.loadingStatus || videoItem.isNotEmpty
|
child: !loadingStatus || videoItem.isNotEmpty
|
||||||
? Column(
|
? Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
InkWell(
|
GestureDetector(
|
||||||
|
behavior: HitTestBehavior.translucent,
|
||||||
onTap: () => showIntroDetail(),
|
onTap: () => showIntroDetail(),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Text(
|
child: Text(
|
||||||
!widget.loadingStatus
|
!loadingStatus
|
||||||
? widget.videoDetail!.title
|
? widget.videoDetail!.title
|
||||||
: videoItem['title'],
|
: videoItem['title'],
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
@ -182,43 +222,27 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
|||||||
return t.highlightColor.withOpacity(0.2);
|
return t.highlightColor.withOpacity(0.2);
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
onPressed: () => showIntroDetail(),
|
onPressed: showIntroDetail,
|
||||||
icon: const Icon(Icons.more_horiz),
|
icon: const Icon(Icons.more_horiz),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
InkWell(
|
GestureDetector(
|
||||||
|
behavior: HitTestBehavior.translucent,
|
||||||
onTap: () => showIntroDetail(),
|
onTap: () => showIntroDetail(),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
StatView(
|
StatView(
|
||||||
theme: 'gray',
|
theme: 'gray', view: viewCount, size: 'medium'),
|
||||||
view: !widget.loadingStatus
|
|
||||||
? widget.videoDetail!.stat!.view
|
|
||||||
: videoItem['stat'].view,
|
|
||||||
size: 'medium',
|
|
||||||
),
|
|
||||||
const SizedBox(width: 10),
|
const SizedBox(width: 10),
|
||||||
StatDanMu(
|
StatDanMu(
|
||||||
theme: 'gray',
|
theme: 'gray', danmu: danmakuCount, size: 'medium'),
|
||||||
danmu: !widget.loadingStatus
|
|
||||||
? widget.videoDetail!.stat!.danmaku
|
|
||||||
: videoItem['stat'].danmaku,
|
|
||||||
size: 'medium',
|
|
||||||
),
|
|
||||||
const SizedBox(width: 10),
|
const SizedBox(width: 10),
|
||||||
Text(
|
Text(
|
||||||
Utils.dateFormat(
|
pubDate,
|
||||||
!widget.loadingStatus
|
style: TextStyle(fontSize: 12, color: outline),
|
||||||
? widget.videoDetail!.pubdate
|
|
||||||
: videoItem['pubdate'],
|
|
||||||
formatType: 'detail'),
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 12,
|
|
||||||
color: t.colorScheme.outline,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -237,7 +261,7 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
|||||||
// 点赞收藏转发 布局样式2
|
// 点赞收藏转发 布局样式2
|
||||||
// actionGrid(context, videoIntroController),
|
// actionGrid(context, videoIntroController),
|
||||||
// 合集
|
// 合集
|
||||||
if (!widget.loadingStatus &&
|
if (!loadingStatus &&
|
||||||
widget.videoDetail!.ugcSeason != null) ...[
|
widget.videoDetail!.ugcSeason != null) ...[
|
||||||
SeasonPanel(
|
SeasonPanel(
|
||||||
ugcSeason: widget.videoDetail!.ugcSeason!,
|
ugcSeason: widget.videoDetail!.ugcSeason!,
|
||||||
@ -248,96 +272,73 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
|||||||
)
|
)
|
||||||
],
|
],
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
onTap: () {
|
onTap: onPushMember,
|
||||||
feedBack();
|
child: Container(
|
||||||
int mid = !widget.loadingStatus
|
padding: const EdgeInsets.symmetric(
|
||||||
? widget.videoDetail!.owner!.mid
|
vertical: 12, horizontal: 4),
|
||||||
: videoItem['owner'].mid;
|
|
||||||
String face = !widget.loadingStatus
|
|
||||||
? widget.videoDetail!.owner!.face
|
|
||||||
: videoItem['owner'].face;
|
|
||||||
Get.toNamed('/member?mid=$mid', arguments: {
|
|
||||||
'face': face,
|
|
||||||
'heroTag': (mid + 99).toString()
|
|
||||||
});
|
|
||||||
},
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.only(
|
|
||||||
top: 12, bottom: 12, left: 4, right: 4),
|
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
NetworkImgLayer(
|
NetworkImgLayer(
|
||||||
type: 'avatar',
|
type: 'avatar',
|
||||||
src: !widget.loadingStatus
|
src: loadingStatus
|
||||||
? widget.videoDetail!.owner!.face
|
? owner.face
|
||||||
: videoItem['owner'].face,
|
: widget.videoDetail!.owner!.face,
|
||||||
width: 34,
|
width: 34,
|
||||||
height: 34,
|
height: 34,
|
||||||
fadeInDuration: Duration.zero,
|
fadeInDuration: Duration.zero,
|
||||||
fadeOutDuration: Duration.zero,
|
fadeOutDuration: Duration.zero,
|
||||||
),
|
),
|
||||||
const SizedBox(width: 10),
|
const SizedBox(width: 10),
|
||||||
Text(
|
Text(owner.name,
|
||||||
!widget.loadingStatus
|
style: const TextStyle(fontSize: 13)),
|
||||||
? widget.videoDetail!.owner!.name
|
|
||||||
: videoItem['owner'].name,
|
|
||||||
style: const TextStyle(fontSize: 13),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 6),
|
const SizedBox(width: 6),
|
||||||
Text(
|
Text(
|
||||||
widget.loadingStatus
|
follower,
|
||||||
? '-'
|
|
||||||
: Utils.numFormat(
|
|
||||||
videoIntroController.userStat['follower']),
|
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: t.textTheme.labelSmall!.fontSize,
|
fontSize: t.textTheme.labelSmall!.fontSize,
|
||||||
color: t.colorScheme.outline),
|
color: outline,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
AnimatedOpacity(
|
AnimatedOpacity(
|
||||||
opacity: widget.loadingStatus ? 0 : 1,
|
opacity: loadingStatus ? 0 : 1,
|
||||||
duration: const Duration(milliseconds: 150),
|
duration: const Duration(milliseconds: 150),
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
height: 32,
|
height: 32,
|
||||||
child: Obx(
|
child: Obx(
|
||||||
() => videoIntroController
|
() =>
|
||||||
.followStatus.isNotEmpty
|
videoIntroController.followStatus.isNotEmpty
|
||||||
? TextButton(
|
? TextButton(
|
||||||
onPressed: () => videoIntroController
|
onPressed: videoIntroController
|
||||||
.actionRelationMod(),
|
.actionRelationMod,
|
||||||
style: TextButton.styleFrom(
|
style: TextButton.styleFrom(
|
||||||
padding: const EdgeInsets.only(
|
padding: const EdgeInsets.only(
|
||||||
left: 8, right: 8),
|
left: 8, right: 8),
|
||||||
foregroundColor:
|
foregroundColor:
|
||||||
videoIntroController.followStatus[
|
followStatus['attribute'] != 0
|
||||||
'attribute'] !=
|
? outline
|
||||||
0
|
: t.colorScheme.onPrimary,
|
||||||
? t.colorScheme.outline
|
backgroundColor:
|
||||||
: t.colorScheme.onPrimary,
|
followStatus['attribute'] != 0
|
||||||
backgroundColor: videoIntroController
|
? t.colorScheme
|
||||||
.followStatus[
|
.onInverseSurface
|
||||||
'attribute'] !=
|
: t.colorScheme
|
||||||
0
|
.primary, // 设置按钮背景色
|
||||||
? t.colorScheme.onInverseSurface
|
),
|
||||||
: t.colorScheme
|
child: Text(
|
||||||
.primary, // 设置按钮背景色
|
followStatus['attribute'] != 0
|
||||||
),
|
? '已关注'
|
||||||
child: Text(
|
: '关注',
|
||||||
videoIntroController.followStatus[
|
style: TextStyle(
|
||||||
'attribute'] !=
|
fontSize: t.textTheme
|
||||||
0
|
.labelMedium!.fontSize),
|
||||||
? '已关注'
|
),
|
||||||
: '关注',
|
)
|
||||||
style: TextStyle(
|
: ElevatedButton(
|
||||||
fontSize: t.textTheme.labelMedium!
|
onPressed: videoIntroController
|
||||||
.fontSize),
|
.actionRelationMod,
|
||||||
),
|
child: const Text('关注'),
|
||||||
)
|
),
|
||||||
: ElevatedButton(
|
|
||||||
onPressed: () => videoIntroController
|
|
||||||
.actionRelationMod(),
|
|
||||||
child: const Text('关注'),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -359,66 +360,64 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
|||||||
|
|
||||||
Widget actionGrid(BuildContext context, videoIntroController) {
|
Widget actionGrid(BuildContext context, videoIntroController) {
|
||||||
return LayoutBuilder(builder: (context, constraints) {
|
return LayoutBuilder(builder: (context, constraints) {
|
||||||
return Padding(
|
return Container(
|
||||||
padding: const EdgeInsets.only(top: 6, bottom: 10),
|
padding: const EdgeInsets.only(top: 6, bottom: 10),
|
||||||
child: SizedBox(
|
height: constraints.maxWidth / 5 * 0.8,
|
||||||
height: constraints.maxWidth / 5 * 0.8,
|
child: GridView.count(
|
||||||
child: GridView.count(
|
primary: false,
|
||||||
primary: false,
|
padding: const EdgeInsets.all(0),
|
||||||
padding: const EdgeInsets.all(0),
|
crossAxisCount: 5,
|
||||||
crossAxisCount: 5,
|
childAspectRatio: 1.25,
|
||||||
childAspectRatio: 1.25,
|
children: <Widget>[
|
||||||
children: <Widget>[
|
Obx(
|
||||||
Obx(
|
() => ActionItem(
|
||||||
() => ActionItem(
|
icon: const Icon(FontAwesomeIcons.thumbsUp),
|
||||||
icon: const Icon(FontAwesomeIcons.thumbsUp),
|
selectIcon: const Icon(FontAwesomeIcons.solidThumbsUp),
|
||||||
selectIcon: const Icon(FontAwesomeIcons.solidThumbsUp),
|
onTap: () => videoIntroController.actionLikeVideo(),
|
||||||
onTap: () => videoIntroController.actionLikeVideo(),
|
selectStatus: videoIntroController.hasLike.value,
|
||||||
selectStatus: videoIntroController.hasLike.value,
|
loadingStatus: loadingStatus,
|
||||||
loadingStatus: widget.loadingStatus,
|
text: !loadingStatus
|
||||||
text: !widget.loadingStatus
|
? widget.videoDetail!.stat!.like!.toString()
|
||||||
? widget.videoDetail!.stat!.like!.toString()
|
|
||||||
: '-'),
|
|
||||||
),
|
|
||||||
ActionItem(
|
|
||||||
icon: const Icon(FontAwesomeIcons.clock),
|
|
||||||
onTap: () => videoIntroController.actionShareVideo(),
|
|
||||||
selectStatus: false,
|
|
||||||
loadingStatus: widget.loadingStatus,
|
|
||||||
text: '稍后再看'),
|
|
||||||
Obx(
|
|
||||||
() => ActionItem(
|
|
||||||
icon: const Icon(FontAwesomeIcons.b),
|
|
||||||
selectIcon: const Icon(FontAwesomeIcons.b),
|
|
||||||
onTap: () => videoIntroController.actionCoinVideo(),
|
|
||||||
selectStatus: videoIntroController.hasCoin.value,
|
|
||||||
loadingStatus: widget.loadingStatus,
|
|
||||||
text: !widget.loadingStatus
|
|
||||||
? widget.videoDetail!.stat!.coin!.toString()
|
|
||||||
: '-'),
|
|
||||||
),
|
|
||||||
Obx(
|
|
||||||
() => ActionItem(
|
|
||||||
icon: const Icon(FontAwesomeIcons.star),
|
|
||||||
selectIcon: const Icon(FontAwesomeIcons.solidStar),
|
|
||||||
// onTap: () => videoIntroController.actionFavVideo(),
|
|
||||||
onTap: () => showFavBottomSheet(),
|
|
||||||
selectStatus: videoIntroController.hasFav.value,
|
|
||||||
loadingStatus: widget.loadingStatus,
|
|
||||||
text: !widget.loadingStatus
|
|
||||||
? widget.videoDetail!.stat!.favorite!.toString()
|
|
||||||
: '-'),
|
|
||||||
),
|
|
||||||
ActionItem(
|
|
||||||
icon: const Icon(FontAwesomeIcons.shareFromSquare),
|
|
||||||
onTap: () => videoIntroController.actionShareVideo(),
|
|
||||||
selectStatus: false,
|
|
||||||
loadingStatus: widget.loadingStatus,
|
|
||||||
text: !widget.loadingStatus
|
|
||||||
? widget.videoDetail!.stat!.share!.toString()
|
|
||||||
: '-'),
|
: '-'),
|
||||||
],
|
),
|
||||||
),
|
ActionItem(
|
||||||
|
icon: const Icon(FontAwesomeIcons.clock),
|
||||||
|
onTap: () => videoIntroController.actionShareVideo(),
|
||||||
|
selectStatus: false,
|
||||||
|
loadingStatus: loadingStatus,
|
||||||
|
text: '稍后再看'),
|
||||||
|
Obx(
|
||||||
|
() => ActionItem(
|
||||||
|
icon: const Icon(FontAwesomeIcons.b),
|
||||||
|
selectIcon: const Icon(FontAwesomeIcons.b),
|
||||||
|
onTap: () => videoIntroController.actionCoinVideo(),
|
||||||
|
selectStatus: videoIntroController.hasCoin.value,
|
||||||
|
loadingStatus: loadingStatus,
|
||||||
|
text: !loadingStatus
|
||||||
|
? widget.videoDetail!.stat!.coin!.toString()
|
||||||
|
: '-'),
|
||||||
|
),
|
||||||
|
Obx(
|
||||||
|
() => ActionItem(
|
||||||
|
icon: const Icon(FontAwesomeIcons.star),
|
||||||
|
selectIcon: const Icon(FontAwesomeIcons.solidStar),
|
||||||
|
// onTap: () => videoIntroController.actionFavVideo(),
|
||||||
|
onTap: () => showFavBottomSheet(),
|
||||||
|
selectStatus: videoIntroController.hasFav.value,
|
||||||
|
loadingStatus: loadingStatus,
|
||||||
|
text: !loadingStatus
|
||||||
|
? widget.videoDetail!.stat!.favorite!.toString()
|
||||||
|
: '-'),
|
||||||
|
),
|
||||||
|
ActionItem(
|
||||||
|
icon: const Icon(FontAwesomeIcons.shareFromSquare),
|
||||||
|
onTap: () => videoIntroController.actionShareVideo(),
|
||||||
|
selectStatus: false,
|
||||||
|
loadingStatus: loadingStatus,
|
||||||
|
text: !loadingStatus
|
||||||
|
? widget.videoDetail!.stat!.share!.toString()
|
||||||
|
: '-'),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@ -431,10 +430,9 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
|||||||
icon: const Icon(FontAwesomeIcons.thumbsUp),
|
icon: const Icon(FontAwesomeIcons.thumbsUp),
|
||||||
onTap: () => videoIntroController.actionLikeVideo(),
|
onTap: () => videoIntroController.actionLikeVideo(),
|
||||||
selectStatus: videoIntroController.hasLike.value,
|
selectStatus: videoIntroController.hasLike.value,
|
||||||
loadingStatus: widget.loadingStatus,
|
loadingStatus: loadingStatus,
|
||||||
text: !widget.loadingStatus
|
text:
|
||||||
? widget.videoDetail!.stat!.like!.toString()
|
!loadingStatus ? widget.videoDetail!.stat!.like!.toString() : '-',
|
||||||
: '-',
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 8),
|
const SizedBox(width: 8),
|
||||||
@ -443,10 +441,9 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
|||||||
icon: const Icon(FontAwesomeIcons.b),
|
icon: const Icon(FontAwesomeIcons.b),
|
||||||
onTap: () => videoIntroController.actionCoinVideo(),
|
onTap: () => videoIntroController.actionCoinVideo(),
|
||||||
selectStatus: videoIntroController.hasCoin.value,
|
selectStatus: videoIntroController.hasCoin.value,
|
||||||
loadingStatus: widget.loadingStatus,
|
loadingStatus: loadingStatus,
|
||||||
text: !widget.loadingStatus
|
text:
|
||||||
? widget.videoDetail!.stat!.coin!.toString()
|
!loadingStatus ? widget.videoDetail!.stat!.coin!.toString() : '-',
|
||||||
: '-',
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 8),
|
const SizedBox(width: 8),
|
||||||
@ -455,8 +452,8 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
|||||||
icon: const Icon(FontAwesomeIcons.heart),
|
icon: const Icon(FontAwesomeIcons.heart),
|
||||||
onTap: () => showFavBottomSheet(),
|
onTap: () => showFavBottomSheet(),
|
||||||
selectStatus: videoIntroController.hasFav.value,
|
selectStatus: videoIntroController.hasFav.value,
|
||||||
loadingStatus: widget.loadingStatus,
|
loadingStatus: loadingStatus,
|
||||||
text: !widget.loadingStatus
|
text: !loadingStatus
|
||||||
? widget.videoDetail!.stat!.favorite!.toString()
|
? widget.videoDetail!.stat!.favorite!.toString()
|
||||||
: '-',
|
: '-',
|
||||||
),
|
),
|
||||||
@ -468,57 +465,20 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
|||||||
videoDetailCtr.tabCtr.animateTo(1);
|
videoDetailCtr.tabCtr.animateTo(1);
|
||||||
},
|
},
|
||||||
selectStatus: false,
|
selectStatus: false,
|
||||||
loadingStatus: widget.loadingStatus,
|
loadingStatus: loadingStatus,
|
||||||
text: !widget.loadingStatus
|
text:
|
||||||
? widget.videoDetail!.stat!.reply!.toString()
|
!loadingStatus ? widget.videoDetail!.stat!.reply!.toString() : '-',
|
||||||
: '-',
|
|
||||||
),
|
),
|
||||||
const SizedBox(width: 8),
|
const SizedBox(width: 8),
|
||||||
ActionRowItem(
|
ActionRowItem(
|
||||||
icon: const Icon(FontAwesomeIcons.share),
|
icon: const Icon(FontAwesomeIcons.share),
|
||||||
onTap: () => videoIntroController.actionShareVideo(),
|
onTap: () => videoIntroController.actionShareVideo(),
|
||||||
selectStatus: false,
|
selectStatus: false,
|
||||||
loadingStatus: widget.loadingStatus,
|
loadingStatus: loadingStatus,
|
||||||
// text: !widget.loadingStatus
|
// text: !loadingStatus
|
||||||
// ? widget.videoDetail!.stat!.share!.toString()
|
// ? widget.videoDetail!.stat!.share!.toString()
|
||||||
// : '-',
|
// : '-',
|
||||||
text: '转发'),
|
text: '转发'),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
InlineSpan buildContent(BuildContext context, content) {
|
|
||||||
String desc = content.desc;
|
|
||||||
List descV2 = content.descV2;
|
|
||||||
// type
|
|
||||||
// 1 普通文本
|
|
||||||
// 2 @用户
|
|
||||||
List<InlineSpan> spanChilds = [];
|
|
||||||
if (descV2.isNotEmpty) {
|
|
||||||
for (var i = 0; i < descV2.length; i++) {
|
|
||||||
if (descV2[i].type == 1) {
|
|
||||||
spanChilds.add(TextSpan(text: descV2[i].rawText));
|
|
||||||
} else if (descV2[i].type == 2) {
|
|
||||||
spanChilds.add(
|
|
||||||
TextSpan(
|
|
||||||
text: '@${descV2[i].rawText}',
|
|
||||||
style: TextStyle(
|
|
||||||
color: Theme.of(context).colorScheme.primary,
|
|
||||||
),
|
|
||||||
recognizer: TapGestureRecognizer()
|
|
||||||
..onTap = () {
|
|
||||||
String heroTag = Utils.makeHeroTag(descV2[i].bizId);
|
|
||||||
Get.toNamed(
|
|
||||||
'/member?mid=${descV2[i].bizId}',
|
|
||||||
arguments: {'face': '', 'heroTag': heroTag},
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
spanChilds.add(TextSpan(text: desc));
|
|
||||||
}
|
|
||||||
return TextSpan(children: spanChilds);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -125,33 +125,29 @@ class IntroDetail extends StatelessWidget {
|
|||||||
// type
|
// type
|
||||||
// 1 普通文本
|
// 1 普通文本
|
||||||
// 2 @用户
|
// 2 @用户
|
||||||
List<InlineSpan> spanChilds = [];
|
List<TextSpan> spanChilds = List.generate(descV2.length, (index) {
|
||||||
if (descV2.isNotEmpty) {
|
final currentDesc = descV2[index];
|
||||||
for (var i = 0; i < descV2.length; i++) {
|
switch (currentDesc.type) {
|
||||||
if (descV2[i].type == 1) {
|
case 1:
|
||||||
spanChilds.add(TextSpan(text: descV2[i].rawText));
|
return TextSpan(text: currentDesc.rawText);
|
||||||
} else if (descV2[i].type == 2) {
|
case 2:
|
||||||
spanChilds.add(
|
final colorSchemePrimary = Theme.of(context).colorScheme.primary;
|
||||||
TextSpan(
|
final heroTag = Utils.makeHeroTag(currentDesc.bizId);
|
||||||
text: '@${descV2[i].rawText}',
|
return TextSpan(
|
||||||
style: TextStyle(
|
text: '@${currentDesc.rawText}',
|
||||||
color: Theme.of(context).colorScheme.primary,
|
style: TextStyle(color: colorSchemePrimary),
|
||||||
),
|
recognizer: TapGestureRecognizer()
|
||||||
recognizer: TapGestureRecognizer()
|
..onTap = () {
|
||||||
..onTap = () {
|
Get.toNamed(
|
||||||
String heroTag = Utils.makeHeroTag(descV2[i].bizId);
|
'/member?mid=${currentDesc.bizId}',
|
||||||
Get.toNamed(
|
arguments: {'face': '', 'heroTag': heroTag},
|
||||||
'/member?mid=${descV2[i].bizId}',
|
);
|
||||||
arguments: {'face': '', 'heroTag': heroTag},
|
},
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
default:
|
||||||
|
return TextSpan();
|
||||||
}
|
}
|
||||||
} else {
|
});
|
||||||
spanChilds.add(TextSpan(text: desc));
|
|
||||||
}
|
|
||||||
return TextSpan(children: spanChilds);
|
return TextSpan(children: spanChilds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -391,6 +391,7 @@ class ReplyItemRow extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
if (replies![i].isUp)
|
if (replies![i].isUp)
|
||||||
const WidgetSpan(
|
const WidgetSpan(
|
||||||
|
alignment: PlaceholderAlignment.top,
|
||||||
child: UpTag(),
|
child: UpTag(),
|
||||||
),
|
),
|
||||||
buildContent(
|
buildContent(
|
||||||
|
|||||||
@ -118,7 +118,7 @@ class _VideoReplyNewDialogState extends State<VideoReplyNewDialog>
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Container(
|
return Container(
|
||||||
height: 400,
|
height: 500,
|
||||||
clipBehavior: Clip.hardEdge,
|
clipBehavior: Clip.hardEdge,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: const BorderRadius.only(
|
borderRadius: const BorderRadius.only(
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'dart:ui';
|
||||||
|
|
||||||
import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart';
|
import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
@ -287,85 +288,43 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
|||||||
onlyOneScrollInBody: true,
|
onlyOneScrollInBody: true,
|
||||||
body: Container(
|
body: Container(
|
||||||
color: Theme.of(context).colorScheme.background,
|
color: Theme.of(context).colorScheme.background,
|
||||||
child: Column(
|
child: Expanded(
|
||||||
children: [
|
child: TabBarView(
|
||||||
Opacity(
|
controller: videoDetailController.tabCtr,
|
||||||
opacity: 0,
|
children: [
|
||||||
child: Container(
|
Builder(
|
||||||
width: double.infinity,
|
builder: (context) {
|
||||||
height: 0,
|
return CustomScrollView(
|
||||||
decoration: BoxDecoration(
|
key: const PageStorageKey<String>('简介'),
|
||||||
border: Border(
|
slivers: <Widget>[
|
||||||
bottom: BorderSide(
|
if (videoDetailController.videoType ==
|
||||||
color: Theme.of(context)
|
SearchType.video) ...[
|
||||||
.dividerColor
|
const VideoIntroPanel(),
|
||||||
.withOpacity(0.1),
|
] else if (videoDetailController.videoType ==
|
||||||
),
|
SearchType.media_bangumi) ...[
|
||||||
),
|
const BangumiIntroPanel()
|
||||||
),
|
],
|
||||||
child: Row(
|
if (videoDetailController.videoType ==
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
SearchType.video) ...[
|
||||||
mainAxisSize: MainAxisSize.max,
|
SliverPersistentHeader(
|
||||||
children: [
|
floating: true,
|
||||||
Container(
|
pinned: true,
|
||||||
width: 280,
|
delegate: SliverHeaderDelegate(
|
||||||
margin: const EdgeInsets.only(left: 20),
|
height: 50,
|
||||||
child: Obx(
|
child: const MenuRow(loadingStatus: false),
|
||||||
() => TabBar(
|
),
|
||||||
controller: videoDetailController.tabCtr,
|
|
||||||
dividerColor: Colors.transparent,
|
|
||||||
indicatorColor:
|
|
||||||
Theme.of(context).colorScheme.background,
|
|
||||||
tabs: videoDetailController.tabs
|
|
||||||
.map((String name) => Tab(text: name))
|
|
||||||
.toList(),
|
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
),
|
const RelatedVideoPanel(),
|
||||||
],
|
],
|
||||||
),
|
);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
),
|
VideoReplyPanel(
|
||||||
Expanded(
|
bvid: videoDetailController.bvid,
|
||||||
child: TabBarView(
|
)
|
||||||
controller: videoDetailController.tabCtr,
|
],
|
||||||
children: [
|
),
|
||||||
Builder(
|
|
||||||
builder: (context) {
|
|
||||||
return CustomScrollView(
|
|
||||||
key: const PageStorageKey<String>('简介'),
|
|
||||||
slivers: <Widget>[
|
|
||||||
if (videoDetailController.videoType ==
|
|
||||||
SearchType.video) ...[
|
|
||||||
const VideoIntroPanel(),
|
|
||||||
] else if (videoDetailController.videoType ==
|
|
||||||
SearchType.media_bangumi) ...[
|
|
||||||
const BangumiIntroPanel()
|
|
||||||
],
|
|
||||||
if (videoDetailController.videoType ==
|
|
||||||
SearchType.video) ...[
|
|
||||||
SliverPersistentHeader(
|
|
||||||
floating: true,
|
|
||||||
pinned: true,
|
|
||||||
delegate: SliverHeaderDelegate(
|
|
||||||
height: 50,
|
|
||||||
child:
|
|
||||||
const MenuRow(loadingStatus: false),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
const RelatedVideoPanel(),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
VideoReplyPanel(
|
|
||||||
bvid: videoDetailController.bvid,
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
Reference in New Issue
Block a user