feat: 一键三连、视频页(取消)收藏

This commit is contained in:
guozhigq
2023-05-13 23:49:39 +08:00
parent 4d85eedd7b
commit 598a293a09
16 changed files with 449 additions and 270 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

View File

@ -1,13 +1,13 @@
import 'package:get/get.dart';
import 'package:flutter/material.dart';
import 'package:pilipala/common/constants.dart';
import 'package:pilipala/common/widgets/stat/up.dart';
import 'package:pilipala/common/widgets/stat/view.dart';
import 'package:pilipala/utils/utils.dart';
import 'package:pilipala/common/widgets/network_img_layer.dart';
// 视频卡片 - 水平布局
class VideoCardH extends StatelessWidget {
// ignore: prefer_typing_uninitialized_variables
var videoItem;
VideoCardH({Key? key, required this.videoItem}) : super(key: key);
@ -138,13 +138,6 @@ class VideoContent extends StatelessWidget {
const SizedBox(height: 4),
Row(
children: [
// Image.asset(
// 'assets/images/up_gray.png',
// width: 14,
// height: 12,
// ),
const UpTag(),
const SizedBox(width: 2),
Text(
videoItem.owner.name,
style: TextStyle(

View File

@ -55,7 +55,7 @@ class Api {
// csrf str CSRF Token位于cookie Cookie方式必要
// https://api.bilibili.com/medialist/gateway/coll/resource/deal
// https://api.bilibili.com/x/v3/fav/resource/deal
static const String favVideo = '/medialist/gateway/coll/resource/deal';
static const String favVideo = '/x/v3/fav/resource/deal';
// 判断视频是否被收藏双端GET
/// aid
@ -68,6 +68,20 @@ class Api {
// bvid str 稿件bvid 必要(可选) avid与bvid任选一个
// csrf str CSRF Token位于cookie 必要
// 一键三连
// https://api.bilibili.com/x/web-interface/archive/like/triple
// aid num 稿件avid 必要(可选) avid与bvid任选一个
// bvid str 稿件bvid 必要(可选) avid与bvid任选一个
// csrf str CSRF Token位于cookie 必要
static const String oneThree = '/x/web-interface/archive/like/triple';
// 获取指定用户创建的所有收藏夹信息
// 该接口也能查询目标内容id存在于那些收藏夹中
// up_mid num 目标用户mid 必要
// type num 目标内容属性 非必要 默认为全部 0全部 2视频稿件
// rid num 目标 视频稿件avid
static const String videoInFolder = '/x/v3/fav/folder/created/list-all';
// 视频详情页 相关视频
static const String relatedList = '/x/web-interface/archive/related';

View File

@ -138,13 +138,14 @@ class Request {
/*
* post请求
*/
post(url, {data, options, cancelToken, extra}) async {
post(url, {data, queryParameters, options, cancelToken, extra}) async {
print('post-data: $data');
Response response;
try {
response = await dio.post(
url,
data: data,
queryParameters: queryParameters,
options: options,
cancelToken: cancelToken,
);

View File

@ -2,6 +2,7 @@ import 'package:pilipala/http/api.dart';
import 'package:pilipala/http/init.dart';
import 'package:pilipala/models/model_hot_video_item.dart';
import 'package:pilipala/models/model_rec_video_item.dart';
import 'package:pilipala/models/user/fav_folder.dart';
import 'package:pilipala/models/video_detail_res.dart';
/// res.data['code'] == 0 请求正常返回结果
@ -122,11 +123,26 @@ class VideoHttp {
}
// 一键三连
static Future oneThree({required String aid}) async {
var res = await Request().post(
Api.oneThree,
queryParameters: {
'aid': aid,
'csrf': await Request.getCsrf(),
},
);
if (res.data['code'] == 0) {
return {'status': true, 'data': res.data['data']};
} else {
return {'status': false, 'data': [], 'msg': res.data['message']};
}
}
// (取消)点赞
static Future likeVideo({required String aid, required bool type}) async {
var res = await Request().post(
Api.likeVideo,
data: {
queryParameters: {
'aid': aid,
'like': type ? 1 : 2,
'csrf': await Request.getCsrf(),
@ -141,20 +157,33 @@ class VideoHttp {
// (取消)收藏
static Future favVideo(
{required String aid, required bool type, required String ids}) async {
Map data = {'rid': aid, 'type': 2};
// type true 添加收藏 false 取消收藏
if (type) {
data['add_media_ids'] = ids;
} else {
data['del_media_ids'] = ids;
}
var res = await Request()
.post(Api.favVideo, data: {'aid': aid, 'like': type ? 1 : 2});
{required String aid,
required bool type,
required String addIds,
required String delIds}) async {
var res = await Request().post(Api.favVideo, queryParameters: {
'rid': aid,
'type': 2,
'add_media_ids': addIds,
'del_media_ids': delIds,
'csrf': await Request.getCsrf(),
});
if (res.data['code'] == 0) {
return {'status': true, 'data': res.data['data']};
} else {
return {'status': false, 'data': []};
}
}
// 查看视频被收藏在哪个文件夹
static Future videoInFolder({required int mid, required String rid}) async {
var res = await Request()
.get(Api.videoInFolder, data: {'up_mid': mid, 'rid': rid});
if (res.data['code'] == 0) {
FavFolderData data = FavFolderData.fromJson(res.data['data']);
return {'status': true, 'data': data};
} else {
return {'status': false, 'data': []};
}
}
}

View File

@ -72,7 +72,7 @@ class FavFolderItemData {
attr = json['attr'];
title = json['title'];
cover = json['cover'];
upper = Upper.fromJson(json['upper']);
upper = json['upper'] != null ? Upper.fromJson(json['upper']) : Upper();
coverType = json['cover_type'];
intro = json['intro'];
ctime = json['ctime'];

View File

@ -167,6 +167,14 @@ class _FavDetailPageState extends State<FavDetailPage> {
if (snapshot.connectionState == ConnectionState.done) {
Map data = snapshot.data;
if (data['status']) {
if (_favDetailController.item!.mediaCount == 0) {
return const SliverToBoxAdapter(
child: SizedBox(
height: 300,
child: Center(child: Text('没有内容')),
),
);
} else {
return Obx(
() => SliverList(
delegate: SliverChildBuilderDelegate((context, index) {
@ -179,6 +187,7 @@ class _FavDetailPageState extends State<FavDetailPage> {
.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('加载中')),
),
);
}

View File

@ -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') {

View File

@ -122,27 +122,44 @@ class _MediaPageState extends State<MediaPage>
SizedBox(
width: double.infinity,
height: 170,
child: ListView(
scrollDirection: Axis.horizontal,
children: [
const SizedBox(width: 20),
FutureBuilder(
child: 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)
]
]
],
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(
@ -155,10 +172,6 @@ class _MediaPageState extends State<MediaPage>
return SizedBox();
}
}),
// for (var i in [1, 2, 3]) ...[const FavFolderItem()],
const SizedBox(width: 10)
],
),
),
],
);
@ -166,11 +179,14 @@ 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(
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(),
}),
@ -220,6 +236,7 @@ class FavFolderItem extends StatelessWidget {
)
],
),
),
);
}
}

View File

@ -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) {

View File

@ -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 {

View File

@ -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();
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();
}
}

View File

@ -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,9 +509,7 @@ class ActionItem extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Material(
child: Ink(
child: InkWell(
return InkWell(
onTap: () => onTap!(),
borderRadius: StyleString.mdRadius,
child: Column(
@ -507,19 +526,16 @@ class ActionItem extends StatelessWidget {
opacity: loadingStatus! ? 0 : 1,
duration: const Duration(milliseconds: 200),
child: Text(
text!,
text ?? '',
style: TextStyle(
color: selectStatus
? Theme.of(context).primaryColor
: Theme.of(context).colorScheme.outline,
fontSize:
Theme.of(context).textTheme.labelSmall?.fontSize),
fontSize: Theme.of(context).textTheme.labelSmall?.fontSize),
),
),
],
),
),
),
);
}
}

View File

@ -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(),
],
);
},

View File

@ -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) {

View File

@ -113,6 +113,7 @@ flutter:
assets:
- assets/images/
- assets/images/lv/
- assets/images/logo/
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware