feat: 一键三连、视频页(取消)收藏
This commit is contained in:
@ -167,18 +167,27 @@ class _FavDetailPageState extends State<FavDetailPage> {
|
||||
if (snapshot.connectionState == ConnectionState.done) {
|
||||
Map data = snapshot.data;
|
||||
if (data['status']) {
|
||||
return Obx(
|
||||
() => SliverList(
|
||||
delegate: SliverChildBuilderDelegate((context, index) {
|
||||
return FavVideoCardH(
|
||||
videoItem: _favDetailController
|
||||
.favDetailData.value.medias![index],
|
||||
);
|
||||
},
|
||||
childCount: _favDetailController
|
||||
.favDetailData.value.medias!.length),
|
||||
),
|
||||
);
|
||||
if (_favDetailController.item!.mediaCount == 0) {
|
||||
return const SliverToBoxAdapter(
|
||||
child: SizedBox(
|
||||
height: 300,
|
||||
child: Center(child: Text('没有内容')),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return Obx(
|
||||
() => SliverList(
|
||||
delegate: SliverChildBuilderDelegate((context, index) {
|
||||
return FavVideoCardH(
|
||||
videoItem: _favDetailController
|
||||
.favDetailData.value.medias![index],
|
||||
);
|
||||
},
|
||||
childCount: _favDetailController
|
||||
.favDetailData.value.medias!.length),
|
||||
),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
return HttpError(
|
||||
errMsg: data['msg'],
|
||||
@ -187,8 +196,9 @@ class _FavDetailPageState extends State<FavDetailPage> {
|
||||
}
|
||||
} else {
|
||||
return const SliverToBoxAdapter(
|
||||
child: Center(
|
||||
child: Text('加载中'),
|
||||
child: SizedBox(
|
||||
height: 300,
|
||||
child: Center(child: Text('加载中')),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -25,7 +25,6 @@ class HomeController extends GetxController {
|
||||
freshIdx: _currentPage,
|
||||
);
|
||||
if (res['status']) {
|
||||
print('type: $type');
|
||||
if (type == 'init') {
|
||||
videoList.value = res['data'];
|
||||
} else if (type == 'onRefresh') {
|
||||
|
@ -122,43 +122,56 @@ class _MediaPageState extends State<MediaPage>
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
height: 170,
|
||||
child: ListView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
children: [
|
||||
const SizedBox(width: 20),
|
||||
FutureBuilder(
|
||||
future: _futureBuilderFuture,
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.connectionState == ConnectionState.done) {
|
||||
Map data = snapshot.data;
|
||||
if (data['status']) {
|
||||
return Obx(() => Row(
|
||||
children: [
|
||||
if (_mediaController.favFolderData.value.list !=
|
||||
null) ...[
|
||||
for (FavFolderItemData i in _mediaController
|
||||
.favFolderData.value.list!) ...[
|
||||
FavFolderItem(item: i),
|
||||
const SizedBox(width: 14)
|
||||
]
|
||||
]
|
||||
],
|
||||
));
|
||||
} else {
|
||||
return SizedBox(
|
||||
height: 160,
|
||||
child: Center(child: Text(data['msg'])),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// 骨架屏
|
||||
return SizedBox();
|
||||
}
|
||||
}),
|
||||
// for (var i in [1, 2, 3]) ...[const FavFolderItem()],
|
||||
const SizedBox(width: 10)
|
||||
],
|
||||
),
|
||||
child: FutureBuilder(
|
||||
future: _futureBuilderFuture,
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.connectionState == ConnectionState.done) {
|
||||
Map data = snapshot.data;
|
||||
if (data['status']) {
|
||||
List favFolderList =
|
||||
_mediaController.favFolderData.value.list!;
|
||||
int favFolderCount =
|
||||
_mediaController.favFolderData.value.count!;
|
||||
bool flag = favFolderCount > favFolderList.length;
|
||||
return Obx(() => ListView.builder(
|
||||
itemCount: _mediaController
|
||||
.favFolderData.value.list!.length +
|
||||
(flag ? 1 : 0),
|
||||
itemBuilder: (context, index) {
|
||||
if (flag && index == favFolderList.length) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
right: 14, bottom: 35),
|
||||
child: Center(
|
||||
child: IconButton(
|
||||
onPressed: () => Get.toNamed('/fav'),
|
||||
icon: Icon(
|
||||
Icons.arrow_forward_ios,
|
||||
size: 18,
|
||||
color: Theme.of(context).primaryColor,
|
||||
),
|
||||
),
|
||||
));
|
||||
} else {
|
||||
return FavFolderItem(
|
||||
item: _mediaController
|
||||
.favFolderData.value.list![index],
|
||||
index: index);
|
||||
}
|
||||
},
|
||||
scrollDirection: Axis.horizontal,
|
||||
));
|
||||
} else {
|
||||
return SizedBox(
|
||||
height: 160,
|
||||
child: Center(child: Text(data['msg'])),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// 骨架屏
|
||||
return SizedBox();
|
||||
}
|
||||
}),
|
||||
),
|
||||
],
|
||||
);
|
||||
@ -166,59 +179,63 @@ class _MediaPageState extends State<MediaPage>
|
||||
}
|
||||
|
||||
class FavFolderItem extends StatelessWidget {
|
||||
FavFolderItem({super.key, this.item});
|
||||
FavFolderItem({super.key, this.item, this.index});
|
||||
FavFolderItemData? item;
|
||||
int? index;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
onTap: () => Get.toNamed('/favDetail', arguments: item, parameters: {
|
||||
'mediaId': item!.id.toString(),
|
||||
}),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const SizedBox(height: 12),
|
||||
Container(
|
||||
width: 180,
|
||||
height: 110,
|
||||
margin: const EdgeInsets.only(bottom: 8),
|
||||
clipBehavior: Clip.hardEdge,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
color: Theme.of(context).colorScheme.onInverseSurface,
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Theme.of(context).colorScheme.onInverseSurface,
|
||||
offset: const Offset(4, -12), // 阴影与容器的距离
|
||||
blurRadius: 0.0, // 高斯的标准偏差与盒子的形状卷积。
|
||||
spreadRadius: 0.0, // 在应用模糊之前,框应该膨胀的量。
|
||||
),
|
||||
],
|
||||
return Container(
|
||||
margin: EdgeInsets.only(left: index == 0 ? 20 : 0, right: 14),
|
||||
child: GestureDetector(
|
||||
onTap: () => Get.toNamed('/favDetail', arguments: item, parameters: {
|
||||
'mediaId': item!.id.toString(),
|
||||
}),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const SizedBox(height: 12),
|
||||
Container(
|
||||
width: 180,
|
||||
height: 110,
|
||||
margin: const EdgeInsets.only(bottom: 8),
|
||||
clipBehavior: Clip.hardEdge,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
color: Theme.of(context).colorScheme.onInverseSurface,
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Theme.of(context).colorScheme.onInverseSurface,
|
||||
offset: const Offset(4, -12), // 阴影与容器的距离
|
||||
blurRadius: 0.0, // 高斯的标准偏差与盒子的形状卷积。
|
||||
spreadRadius: 0.0, // 在应用模糊之前,框应该膨胀的量。
|
||||
),
|
||||
],
|
||||
),
|
||||
child: LayoutBuilder(
|
||||
builder: (context, BoxConstraints box) {
|
||||
return NetworkImgLayer(
|
||||
src: item!.cover,
|
||||
width: box.maxWidth,
|
||||
height: box.maxHeight,
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
child: LayoutBuilder(
|
||||
builder: (context, BoxConstraints box) {
|
||||
return NetworkImgLayer(
|
||||
src: item!.cover,
|
||||
width: box.maxWidth,
|
||||
height: box.maxHeight,
|
||||
);
|
||||
},
|
||||
Text(
|
||||
' ${item!.title}',
|
||||
overflow: TextOverflow.fade,
|
||||
maxLines: 1,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
' ${item!.title}',
|
||||
overflow: TextOverflow.fade,
|
||||
maxLines: 1,
|
||||
),
|
||||
Text(
|
||||
' 共${item!.mediaCount}条视频',
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.labelSmall!
|
||||
.copyWith(color: Theme.of(context).colorScheme.outline),
|
||||
)
|
||||
],
|
||||
Text(
|
||||
' 共${item!.mediaCount}条视频',
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.labelSmall!
|
||||
.copyWith(color: Theme.of(context).colorScheme.outline),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -27,6 +27,9 @@ class MineController extends GetxController {
|
||||
}
|
||||
|
||||
Future queryUserInfo() async {
|
||||
if (user.get(UserBoxKey.userLogin) == null) {
|
||||
return {'status': false};
|
||||
}
|
||||
var res = await UserHttp.userInfo();
|
||||
if (res['status']) {
|
||||
if (res['data'].isLogin) {
|
||||
|
@ -64,6 +64,7 @@ class _MinePageState extends State<MinePage> {
|
||||
future: _mineController.queryUserInfo(),
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.connectionState == ConnectionState.done) {
|
||||
print(snapshot.data);
|
||||
if (snapshot.data['status']) {
|
||||
return Obx(() => userInfoBuild());
|
||||
} else {
|
||||
|
@ -1,10 +1,13 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:pilipala/http/user.dart';
|
||||
import 'package:pilipala/http/video.dart';
|
||||
import 'package:pilipala/models/user/fav_folder.dart';
|
||||
import 'package:pilipala/models/video_detail_res.dart';
|
||||
import 'package:pilipala/pages/video/detail/controller.dart';
|
||||
import 'package:pilipala/utils/storage.dart';
|
||||
|
||||
class VideoIntroController extends GetxController {
|
||||
// 视频aid
|
||||
@ -34,6 +37,11 @@ class VideoIntroController extends GetxController {
|
||||
RxBool hasCoin = false.obs;
|
||||
// 是否收藏
|
||||
RxBool hasFav = false.obs;
|
||||
Box user = GStrorage.user;
|
||||
bool userLogin = false;
|
||||
Rx<FavFolderData> favFolderData = FavFolderData().obs;
|
||||
List addMediaIdsNew = [];
|
||||
List delMediaIdsNew = [];
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
@ -51,6 +59,7 @@ class VideoIntroController extends GetxController {
|
||||
videoItem!['owner'] = args.owner;
|
||||
}
|
||||
}
|
||||
userLogin = user.get(UserBoxKey.userLogin) != null;
|
||||
}
|
||||
|
||||
// 获取视频简介
|
||||
@ -66,12 +75,14 @@ class VideoIntroController extends GetxController {
|
||||
}
|
||||
// 获取到粉丝数再返回
|
||||
await queryUserStat();
|
||||
// 获取点赞状态
|
||||
queryHasLikeVideo();
|
||||
// 获取投币状态
|
||||
queryHasCoinVideo();
|
||||
// 获取收藏状态
|
||||
queryHasFavVideo();
|
||||
if (userLogin) {
|
||||
// 获取点赞状态
|
||||
queryHasLikeVideo();
|
||||
// 获取投币状态
|
||||
queryHasCoinVideo();
|
||||
// 获取收藏状态
|
||||
queryHasFavVideo();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -104,12 +115,54 @@ class VideoIntroController extends GetxController {
|
||||
}
|
||||
|
||||
// 一键三连
|
||||
Future actionOneThree() async {
|
||||
if (hasLike.value && hasCoin.value && hasFav.value) {
|
||||
// 已点赞、投币、收藏
|
||||
SmartDialog.showToast('🙏 UP已经收到了~');
|
||||
return false;
|
||||
}
|
||||
SmartDialog.show(
|
||||
useSystem: true,
|
||||
animationType: SmartAnimationType.centerFade_otherSlide,
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
title: const Text('提示'),
|
||||
content: const Text('一键三连 给UP送温暖'),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => SmartDialog.dismiss(),
|
||||
child: const Text('点错了')),
|
||||
TextButton(
|
||||
onPressed: () async {
|
||||
var result = await VideoHttp.oneThree(aid: aid);
|
||||
if (result['status']) {
|
||||
hasLike.value = result["data"]["like"];
|
||||
hasCoin.value = result["data"]["coin"];
|
||||
hasFav.value = result["data"]["fav"];
|
||||
SmartDialog.showToast('三连成功 🎉');
|
||||
} else {
|
||||
SmartDialog.showToast(result['msg']);
|
||||
}
|
||||
SmartDialog.dismiss();
|
||||
},
|
||||
child: const Text('确认'),
|
||||
)
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
// (取消)点赞
|
||||
Future actionLikeVideo() async {
|
||||
var result = await VideoHttp.likeVideo(aid: aid, type: !hasLike.value);
|
||||
if (result['status']) {
|
||||
hasLike.value = result["data"] == 1 ? true : false;
|
||||
if (hasLike.value) {
|
||||
SmartDialog.showToast('已点赞 👍');
|
||||
} else {
|
||||
SmartDialog.showToast('取消赞');
|
||||
}
|
||||
} else {
|
||||
SmartDialog.showToast(result['msg']);
|
||||
}
|
||||
@ -122,12 +175,58 @@ class VideoIntroController extends GetxController {
|
||||
|
||||
// (取消)收藏
|
||||
Future actionFavVideo() async {
|
||||
print('(取消)收藏');
|
||||
// var result = await VideoHttp.favVideo(aid: aid, type: true, ids: '');
|
||||
try {
|
||||
for (var i in favFolderData.value.list!.toList()) {
|
||||
if (i.favState == 1) {
|
||||
addMediaIdsNew.add(i.id);
|
||||
} else {
|
||||
delMediaIdsNew.add(i.id);
|
||||
}
|
||||
}
|
||||
} catch (e) {}
|
||||
var result = await VideoHttp.favVideo(
|
||||
aid: aid,
|
||||
type: true,
|
||||
addIds: addMediaIdsNew.join(','),
|
||||
delIds: delMediaIdsNew.join(','));
|
||||
if (result['status']) {
|
||||
if (result['data']['prompt']) {
|
||||
addMediaIdsNew = [];
|
||||
delMediaIdsNew = [];
|
||||
Get.back();
|
||||
// 重新获取收藏状态
|
||||
queryHasFavVideo();
|
||||
SmartDialog.showToast('✅ 操作成功');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 分享视频
|
||||
Future actionShareVideo() async {
|
||||
print('分享视频');
|
||||
}
|
||||
|
||||
Future queryVideoInFolder() async {
|
||||
var result = await VideoHttp.videoInFolder(
|
||||
mid: user.get(UserBoxKey.userMid), rid: aid);
|
||||
if (result['status']) {
|
||||
favFolderData.value = result['data'];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// 选择文件夹
|
||||
onChoose(bool checkValue, int index) {
|
||||
List<FavFolderItemData> datalist = favFolderData.value.list!;
|
||||
for (var i = 0; i < datalist.length; i++) {
|
||||
if (i == index) {
|
||||
datalist[i].favState = checkValue == true ? 1 : 0;
|
||||
datalist[i].mediaCount = checkValue == true
|
||||
? datalist[i].mediaCount! + 1
|
||||
: datalist[i].mediaCount! - 1;
|
||||
}
|
||||
}
|
||||
favFolderData.value.list = datalist;
|
||||
favFolderData.refresh();
|
||||
}
|
||||
}
|
||||
|
@ -54,10 +54,7 @@ class _VideoIntroPanelState extends State<VideoIntroPanel>
|
||||
if (snapshot.data['status']) {
|
||||
// 请求成功
|
||||
// return _buildView(context, false, videoDetail);
|
||||
return VideoInfo(
|
||||
loadingStatus: false,
|
||||
videoDetail: videoDetail,
|
||||
videoIntroController: videoIntroController);
|
||||
return VideoInfo(loadingStatus: false, videoDetail: videoDetail);
|
||||
} else {
|
||||
// 请求错误
|
||||
return HttpError(
|
||||
@ -66,10 +63,7 @@ class _VideoIntroPanelState extends State<VideoIntroPanel>
|
||||
);
|
||||
}
|
||||
} else {
|
||||
return VideoInfo(
|
||||
loadingStatus: true,
|
||||
videoDetail: videoDetail,
|
||||
videoIntroController: videoIntroController);
|
||||
return VideoInfo(loadingStatus: true, videoDetail: videoDetail);
|
||||
}
|
||||
},
|
||||
);
|
||||
@ -79,13 +73,8 @@ class _VideoIntroPanelState extends State<VideoIntroPanel>
|
||||
class VideoInfo extends StatefulWidget {
|
||||
bool loadingStatus = false;
|
||||
VideoDetailData? videoDetail;
|
||||
VideoIntroController? videoIntroController;
|
||||
|
||||
VideoInfo(
|
||||
{Key? key,
|
||||
required this.loadingStatus,
|
||||
this.videoDetail,
|
||||
this.videoIntroController})
|
||||
VideoInfo({Key? key, required this.loadingStatus, this.videoDetail})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
@ -94,6 +83,8 @@ class VideoInfo extends StatefulWidget {
|
||||
|
||||
class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
||||
Map videoItem = Get.put(VideoIntroController()).videoItem!;
|
||||
final VideoIntroController videoIntroController =
|
||||
Get.put(VideoIntroController(), tag: Get.arguments['heroTag']);
|
||||
bool isExpand = false;
|
||||
|
||||
/// 手动控制动画的控制器
|
||||
@ -137,7 +128,7 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Get.back(),
|
||||
onPressed: () => videoIntroController.actionFavVideo(),
|
||||
child: const Text('完成'),
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
@ -146,30 +137,34 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
||||
Expanded(
|
||||
child: Material(
|
||||
child: FutureBuilder(
|
||||
future: _favController.queryFavFolder(),
|
||||
future: videoIntroController.queryVideoInFolder(),
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.connectionState == ConnectionState.done) {
|
||||
Map data = snapshot.data as Map;
|
||||
if (data['status']) {
|
||||
return Obx(
|
||||
() => ListView.builder(
|
||||
itemCount: _favController
|
||||
itemCount: videoIntroController
|
||||
.favFolderData.value.list!.length +
|
||||
1,
|
||||
itemBuilder: (context, index) {
|
||||
if (index == 0) {
|
||||
return const SizedBox(height: 15);
|
||||
return const SizedBox(height: 10);
|
||||
} else {
|
||||
return ListTile(
|
||||
onTap: () {},
|
||||
onTap: () => videoIntroController.onChoose(
|
||||
videoIntroController.favFolderData.value
|
||||
.list![index - 1].favState !=
|
||||
1,
|
||||
index - 1),
|
||||
dense: true,
|
||||
leading:
|
||||
const Icon(Icons.folder_special_outlined),
|
||||
minLeadingWidth: 0,
|
||||
title: Text(_favController.favFolderData.value
|
||||
.list![index - 1].title!),
|
||||
title: Text(videoIntroController.favFolderData
|
||||
.value.list![index - 1].title!),
|
||||
subtitle: Text(
|
||||
'${_favController.favFolderData.value.list![index - 1].mediaCount}个内容',
|
||||
'${videoIntroController.favFolderData.value.list![index - 1].mediaCount}个内容',
|
||||
style: TextStyle(
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
@ -182,8 +177,15 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
||||
trailing: Transform.scale(
|
||||
scale: 0.9,
|
||||
child: Checkbox(
|
||||
value: false,
|
||||
onChanged: (bool? checkValue) {},
|
||||
value: videoIntroController
|
||||
.favFolderData
|
||||
.value
|
||||
.list![index - 1]
|
||||
.favState ==
|
||||
1,
|
||||
onChanged: (bool? checkValue) =>
|
||||
videoIntroController.onChoose(
|
||||
checkValue!, index - 1),
|
||||
),
|
||||
),
|
||||
);
|
||||
@ -302,65 +304,6 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
Row(
|
||||
children: [
|
||||
NetworkImgLayer(
|
||||
type: 'avatar',
|
||||
src: !widget.loadingStatus
|
||||
? widget.videoDetail!.owner!.face
|
||||
: videoItem['owner'].face,
|
||||
width: 38,
|
||||
height: 38,
|
||||
fadeInDuration: Duration.zero,
|
||||
fadeOutDuration: Duration.zero,
|
||||
),
|
||||
const SizedBox(width: 14),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(!widget.loadingStatus
|
||||
? widget.videoDetail!.owner!.name
|
||||
: videoItem['owner'].name),
|
||||
// const SizedBox(width: 10),
|
||||
Text(
|
||||
widget.loadingStatus
|
||||
? '- 粉丝'
|
||||
: '${Utils.numFormat(widget.videoIntroController!.userStat['follower'])}粉丝',
|
||||
style: TextStyle(
|
||||
fontSize: Theme.of(context)
|
||||
.textTheme
|
||||
.labelSmall!
|
||||
.fontSize,
|
||||
color: Theme.of(context).colorScheme.outline),
|
||||
),
|
||||
],
|
||||
),
|
||||
const Spacer(),
|
||||
AnimatedOpacity(
|
||||
opacity: widget.loadingStatus ? 0 : 1,
|
||||
duration: const Duration(milliseconds: 150),
|
||||
child: SizedBox(
|
||||
height: 36,
|
||||
child: ElevatedButton(
|
||||
onPressed: () {},
|
||||
child: Row(
|
||||
children: const [
|
||||
Icon(
|
||||
CupertinoIcons.plus,
|
||||
size: 16,
|
||||
),
|
||||
SizedBox(width: 4),
|
||||
Text('关注'),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
// 简介 默认收起
|
||||
if (!widget.loadingStatus)
|
||||
ExpandedSection(
|
||||
@ -392,8 +335,64 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 5),
|
||||
_actionGrid(context, widget.videoIntroController),
|
||||
const SizedBox(height: 8),
|
||||
_actionGrid(context, videoIntroController),
|
||||
Divider(
|
||||
height: 26,
|
||||
color: Theme.of(context).dividerColor.withOpacity(0.1),
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
NetworkImgLayer(
|
||||
type: 'avatar',
|
||||
src: !widget.loadingStatus
|
||||
? widget.videoDetail!.owner!.face
|
||||
: videoItem['owner'].face,
|
||||
width: 38,
|
||||
height: 38,
|
||||
fadeInDuration: Duration.zero,
|
||||
fadeOutDuration: Duration.zero,
|
||||
),
|
||||
const SizedBox(width: 14),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(!widget.loadingStatus
|
||||
? widget.videoDetail!.owner!.name
|
||||
: videoItem['owner'].name),
|
||||
// const SizedBox(width: 10),
|
||||
Text(
|
||||
widget.loadingStatus
|
||||
? '- 粉丝'
|
||||
: '${Utils.numFormat(videoIntroController.userStat['follower'])}粉丝',
|
||||
style: TextStyle(
|
||||
fontSize: Theme.of(context)
|
||||
.textTheme
|
||||
.labelSmall!
|
||||
.fontSize,
|
||||
color: Theme.of(context).colorScheme.outline),
|
||||
),
|
||||
],
|
||||
),
|
||||
const Spacer(),
|
||||
AnimatedOpacity(
|
||||
opacity: widget.loadingStatus ? 0 : 1,
|
||||
duration: const Duration(milliseconds: 150),
|
||||
child: SizedBox(
|
||||
height: 36,
|
||||
child: ElevatedButton(
|
||||
onPressed: () {},
|
||||
child: const Text('关注'),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Divider(
|
||||
height: 26,
|
||||
color: Theme.of(context).dividerColor.withOpacity(0.1),
|
||||
),
|
||||
// const SizedBox(height: 10),
|
||||
],
|
||||
)
|
||||
: const Center(child: CircularProgressIndicator()),
|
||||
@ -412,6 +411,29 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
||||
crossAxisCount: 5,
|
||||
childAspectRatio: 1.25,
|
||||
children: <Widget>[
|
||||
// ActionItem(
|
||||
// icon: const Icon(FontAwesomeIcons.s),
|
||||
// selectIcon: const Icon(FontAwesomeIcons.s),
|
||||
// onTap: () => {},
|
||||
// selectStatus: true,
|
||||
// loadingStatus: false,
|
||||
// text: '三连',
|
||||
// ),
|
||||
// Column(
|
||||
// children: [],
|
||||
// ),
|
||||
InkWell(
|
||||
onTap: () => videoIntroController.actionOneThree(),
|
||||
borderRadius: StyleString.mdRadius,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(12),
|
||||
child: Image.asset(
|
||||
'assets/images/logo/logo_big.png',
|
||||
width: 10,
|
||||
height: 10,
|
||||
),
|
||||
),
|
||||
),
|
||||
Obx(
|
||||
() => ActionItem(
|
||||
icon: const Icon(FontAwesomeIcons.thumbsUp),
|
||||
@ -423,13 +445,13 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
||||
? widget.videoDetail!.stat!.like!.toString()
|
||||
: '-'),
|
||||
),
|
||||
ActionItem(
|
||||
icon: const Icon(FontAwesomeIcons.thumbsDown),
|
||||
selectIcon: const Icon(FontAwesomeIcons.solidThumbsDown),
|
||||
onTap: () => {},
|
||||
selectStatus: false,
|
||||
loadingStatus: widget.loadingStatus,
|
||||
text: '不喜欢'),
|
||||
// ActionItem(
|
||||
// icon: const Icon(FontAwesomeIcons.thumbsDown),
|
||||
// selectIcon: const Icon(FontAwesomeIcons.solidThumbsDown),
|
||||
// onTap: () => {},
|
||||
// selectStatus: false,
|
||||
// loadingStatus: widget.loadingStatus,
|
||||
// text: '不喜欢'),
|
||||
Obx(
|
||||
() => ActionItem(
|
||||
icon: const Icon(FontAwesomeIcons.b),
|
||||
@ -445,7 +467,6 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
||||
() => ActionItem(
|
||||
icon: const Icon(FontAwesomeIcons.star),
|
||||
selectIcon: const Icon(FontAwesomeIcons.star),
|
||||
// onTap: () => videoIntroController.actionFavVideo(),
|
||||
onTap: () => showFavBottomSheet(),
|
||||
selectStatus: videoIntroController.hasFav.value,
|
||||
loadingStatus: widget.loadingStatus,
|
||||
@ -488,37 +509,32 @@ class ActionItem extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Material(
|
||||
child: Ink(
|
||||
child: InkWell(
|
||||
onTap: () => onTap!(),
|
||||
borderRadius: StyleString.mdRadius,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const SizedBox(height: 4),
|
||||
selectStatus
|
||||
? Icon(selectIcon!.icon!,
|
||||
size: 21, color: Theme.of(context).primaryColor)
|
||||
: Icon(icon!.icon!,
|
||||
size: 21, color: Theme.of(context).colorScheme.outline),
|
||||
const SizedBox(height: 4),
|
||||
AnimatedOpacity(
|
||||
opacity: loadingStatus! ? 0 : 1,
|
||||
duration: const Duration(milliseconds: 200),
|
||||
child: Text(
|
||||
text!,
|
||||
style: TextStyle(
|
||||
color: selectStatus
|
||||
? Theme.of(context).primaryColor
|
||||
: Theme.of(context).colorScheme.outline,
|
||||
fontSize:
|
||||
Theme.of(context).textTheme.labelSmall?.fontSize),
|
||||
),
|
||||
),
|
||||
],
|
||||
return InkWell(
|
||||
onTap: () => onTap!(),
|
||||
borderRadius: StyleString.mdRadius,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const SizedBox(height: 4),
|
||||
selectStatus
|
||||
? Icon(selectIcon!.icon!,
|
||||
size: 21, color: Theme.of(context).primaryColor)
|
||||
: Icon(icon!.icon!,
|
||||
size: 21, color: Theme.of(context).colorScheme.outline),
|
||||
const SizedBox(height: 4),
|
||||
AnimatedOpacity(
|
||||
opacity: loadingStatus! ? 0 : 1,
|
||||
duration: const Duration(milliseconds: 200),
|
||||
child: Text(
|
||||
text ?? '',
|
||||
style: TextStyle(
|
||||
color: selectStatus
|
||||
? Theme.of(context).primaryColor
|
||||
: Theme.of(context).colorScheme.outline,
|
||||
fontSize: Theme.of(context).textTheme.labelSmall?.fontSize),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -114,23 +114,11 @@ class _VideoDetailPageState extends State<VideoDetailPage> {
|
||||
children: [
|
||||
Builder(
|
||||
builder: (context) {
|
||||
return CustomScrollView(
|
||||
key: const PageStorageKey<String>('简介'),
|
||||
return const CustomScrollView(
|
||||
key: PageStorageKey<String>('简介'),
|
||||
slivers: <Widget>[
|
||||
const VideoIntroPanel(),
|
||||
SliverPadding(
|
||||
padding:
|
||||
const EdgeInsets.only(top: 8, bottom: 5),
|
||||
sliver: SliverToBoxAdapter(
|
||||
child: Divider(
|
||||
height: 1,
|
||||
color: Theme.of(context)
|
||||
.dividerColor
|
||||
.withOpacity(0.1),
|
||||
),
|
||||
),
|
||||
),
|
||||
const RelatedVideoPanel(),
|
||||
VideoIntroPanel(),
|
||||
RelatedVideoPanel(),
|
||||
],
|
||||
);
|
||||
},
|
||||
|
@ -1,10 +1,13 @@
|
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:pilipala/http/constants.dart';
|
||||
import 'package:pilipala/http/init.dart';
|
||||
import 'package:pilipala/http/user.dart';
|
||||
import 'package:pilipala/pages/home/index.dart';
|
||||
import 'package:pilipala/pages/mine/index.dart';
|
||||
import 'package:pilipala/utils/cookie.dart';
|
||||
import 'package:pilipala/utils/storage.dart';
|
||||
import 'package:webview_cookie_manager/webview_cookie_manager.dart';
|
||||
import 'package:webview_flutter/webview_flutter.dart';
|
||||
|
||||
@ -52,10 +55,15 @@ class WebviewController extends GetxController {
|
||||
await WebviewCookieManager().getCookies(HttpString.baseUrl);
|
||||
await SetCookie.onSet(cookies, HttpString.baseUrl);
|
||||
await SetCookie.onSet(apiCookies, HttpString.baseApiUrl);
|
||||
await UserHttp.userInfo();
|
||||
var result = await UserHttp.userInfo();
|
||||
print('网页登录: $result');
|
||||
if (result['status'] && result['data'].isLogin) {
|
||||
SmartDialog.showToast('登录成功');
|
||||
Get.find<MineController>().userInfo = result['data'];
|
||||
Box user = GStrorage.user;
|
||||
user.put(UserBoxKey.userLogin, true);
|
||||
Get.find<MineController>().userInfo.value = result['data'];
|
||||
Get.find<HomeController>().queryRcmdFeed('onRefresh');
|
||||
Get.back();
|
||||
}
|
||||
} catch (e) {
|
||||
|
Reference in New Issue
Block a user