feat: 一键三连、视频页(取消)收藏
This commit is contained in:
BIN
assets/images/logo/logo_big.png
Normal file
BIN
assets/images/logo/logo_big.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 45 KiB |
@ -1,13 +1,13 @@
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:pilipala/common/constants.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/common/widgets/stat/view.dart';
|
||||||
import 'package:pilipala/utils/utils.dart';
|
import 'package:pilipala/utils/utils.dart';
|
||||||
import 'package:pilipala/common/widgets/network_img_layer.dart';
|
import 'package:pilipala/common/widgets/network_img_layer.dart';
|
||||||
|
|
||||||
// 视频卡片 - 水平布局
|
// 视频卡片 - 水平布局
|
||||||
class VideoCardH extends StatelessWidget {
|
class VideoCardH extends StatelessWidget {
|
||||||
|
// ignore: prefer_typing_uninitialized_variables
|
||||||
var videoItem;
|
var videoItem;
|
||||||
|
|
||||||
VideoCardH({Key? key, required this.videoItem}) : super(key: key);
|
VideoCardH({Key? key, required this.videoItem}) : super(key: key);
|
||||||
@ -138,13 +138,6 @@ class VideoContent extends StatelessWidget {
|
|||||||
const SizedBox(height: 4),
|
const SizedBox(height: 4),
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
// Image.asset(
|
|
||||||
// 'assets/images/up_gray.png',
|
|
||||||
// width: 14,
|
|
||||||
// height: 12,
|
|
||||||
// ),
|
|
||||||
const UpTag(),
|
|
||||||
const SizedBox(width: 2),
|
|
||||||
Text(
|
Text(
|
||||||
videoItem.owner.name,
|
videoItem.owner.name,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
|
@ -55,7 +55,7 @@ class Api {
|
|||||||
// csrf str CSRF Token(位于cookie) Cookie方式必要
|
// csrf str CSRF Token(位于cookie) Cookie方式必要
|
||||||
// https://api.bilibili.com/medialist/gateway/coll/resource/deal
|
// https://api.bilibili.com/medialist/gateway/coll/resource/deal
|
||||||
// https://api.bilibili.com/x/v3/fav/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
|
// 判断视频是否被收藏(双端)GET
|
||||||
/// aid
|
/// aid
|
||||||
@ -68,6 +68,20 @@ class Api {
|
|||||||
// bvid str 稿件bvid 必要(可选) avid与bvid任选一个
|
// bvid str 稿件bvid 必要(可选) avid与bvid任选一个
|
||||||
// csrf str CSRF Token(位于cookie) 必要
|
// 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';
|
static const String relatedList = '/x/web-interface/archive/related';
|
||||||
|
|
||||||
|
@ -138,13 +138,14 @@ class Request {
|
|||||||
/*
|
/*
|
||||||
* post请求
|
* post请求
|
||||||
*/
|
*/
|
||||||
post(url, {data, options, cancelToken, extra}) async {
|
post(url, {data, queryParameters, options, cancelToken, extra}) async {
|
||||||
print('post-data: $data');
|
print('post-data: $data');
|
||||||
Response response;
|
Response response;
|
||||||
try {
|
try {
|
||||||
response = await dio.post(
|
response = await dio.post(
|
||||||
url,
|
url,
|
||||||
data: data,
|
data: data,
|
||||||
|
queryParameters: queryParameters,
|
||||||
options: options,
|
options: options,
|
||||||
cancelToken: cancelToken,
|
cancelToken: cancelToken,
|
||||||
);
|
);
|
||||||
|
@ -2,6 +2,7 @@ import 'package:pilipala/http/api.dart';
|
|||||||
import 'package:pilipala/http/init.dart';
|
import 'package:pilipala/http/init.dart';
|
||||||
import 'package:pilipala/models/model_hot_video_item.dart';
|
import 'package:pilipala/models/model_hot_video_item.dart';
|
||||||
import 'package:pilipala/models/model_rec_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';
|
import 'package:pilipala/models/video_detail_res.dart';
|
||||||
|
|
||||||
/// res.data['code'] == 0 请求正常返回结果
|
/// 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 {
|
static Future likeVideo({required String aid, required bool type}) async {
|
||||||
var res = await Request().post(
|
var res = await Request().post(
|
||||||
Api.likeVideo,
|
Api.likeVideo,
|
||||||
data: {
|
queryParameters: {
|
||||||
'aid': aid,
|
'aid': aid,
|
||||||
'like': type ? 1 : 2,
|
'like': type ? 1 : 2,
|
||||||
'csrf': await Request.getCsrf(),
|
'csrf': await Request.getCsrf(),
|
||||||
@ -141,20 +157,33 @@ class VideoHttp {
|
|||||||
|
|
||||||
// (取消)收藏
|
// (取消)收藏
|
||||||
static Future favVideo(
|
static Future favVideo(
|
||||||
{required String aid, required bool type, required String ids}) async {
|
{required String aid,
|
||||||
Map data = {'rid': aid, 'type': 2};
|
required bool type,
|
||||||
// type true 添加收藏 false 取消收藏
|
required String addIds,
|
||||||
if (type) {
|
required String delIds}) async {
|
||||||
data['add_media_ids'] = ids;
|
var res = await Request().post(Api.favVideo, queryParameters: {
|
||||||
} else {
|
'rid': aid,
|
||||||
data['del_media_ids'] = ids;
|
'type': 2,
|
||||||
}
|
'add_media_ids': addIds,
|
||||||
var res = await Request()
|
'del_media_ids': delIds,
|
||||||
.post(Api.favVideo, data: {'aid': aid, 'like': type ? 1 : 2});
|
'csrf': await Request.getCsrf(),
|
||||||
|
});
|
||||||
if (res.data['code'] == 0) {
|
if (res.data['code'] == 0) {
|
||||||
return {'status': true, 'data': res.data['data']};
|
return {'status': true, 'data': res.data['data']};
|
||||||
} else {
|
} else {
|
||||||
return {'status': false, 'data': []};
|
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': []};
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,7 @@ class FavFolderItemData {
|
|||||||
attr = json['attr'];
|
attr = json['attr'];
|
||||||
title = json['title'];
|
title = json['title'];
|
||||||
cover = json['cover'];
|
cover = json['cover'];
|
||||||
upper = Upper.fromJson(json['upper']);
|
upper = json['upper'] != null ? Upper.fromJson(json['upper']) : Upper();
|
||||||
coverType = json['cover_type'];
|
coverType = json['cover_type'];
|
||||||
intro = json['intro'];
|
intro = json['intro'];
|
||||||
ctime = json['ctime'];
|
ctime = json['ctime'];
|
||||||
|
@ -167,18 +167,27 @@ class _FavDetailPageState extends State<FavDetailPage> {
|
|||||||
if (snapshot.connectionState == ConnectionState.done) {
|
if (snapshot.connectionState == ConnectionState.done) {
|
||||||
Map data = snapshot.data;
|
Map data = snapshot.data;
|
||||||
if (data['status']) {
|
if (data['status']) {
|
||||||
return Obx(
|
if (_favDetailController.item!.mediaCount == 0) {
|
||||||
() => SliverList(
|
return const SliverToBoxAdapter(
|
||||||
delegate: SliverChildBuilderDelegate((context, index) {
|
child: SizedBox(
|
||||||
return FavVideoCardH(
|
height: 300,
|
||||||
videoItem: _favDetailController
|
child: Center(child: Text('没有内容')),
|
||||||
.favDetailData.value.medias![index],
|
),
|
||||||
);
|
);
|
||||||
},
|
} else {
|
||||||
childCount: _favDetailController
|
return Obx(
|
||||||
.favDetailData.value.medias!.length),
|
() => SliverList(
|
||||||
),
|
delegate: SliverChildBuilderDelegate((context, index) {
|
||||||
);
|
return FavVideoCardH(
|
||||||
|
videoItem: _favDetailController
|
||||||
|
.favDetailData.value.medias![index],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
childCount: _favDetailController
|
||||||
|
.favDetailData.value.medias!.length),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return HttpError(
|
return HttpError(
|
||||||
errMsg: data['msg'],
|
errMsg: data['msg'],
|
||||||
@ -187,8 +196,9 @@ class _FavDetailPageState extends State<FavDetailPage> {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return const SliverToBoxAdapter(
|
return const SliverToBoxAdapter(
|
||||||
child: Center(
|
child: SizedBox(
|
||||||
child: Text('加载中'),
|
height: 300,
|
||||||
|
child: Center(child: Text('加载中')),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,6 @@ class HomeController extends GetxController {
|
|||||||
freshIdx: _currentPage,
|
freshIdx: _currentPage,
|
||||||
);
|
);
|
||||||
if (res['status']) {
|
if (res['status']) {
|
||||||
print('type: $type');
|
|
||||||
if (type == 'init') {
|
if (type == 'init') {
|
||||||
videoList.value = res['data'];
|
videoList.value = res['data'];
|
||||||
} else if (type == 'onRefresh') {
|
} else if (type == 'onRefresh') {
|
||||||
|
@ -122,43 +122,56 @@ class _MediaPageState extends State<MediaPage>
|
|||||||
SizedBox(
|
SizedBox(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
height: 170,
|
height: 170,
|
||||||
child: ListView(
|
child: FutureBuilder(
|
||||||
scrollDirection: Axis.horizontal,
|
future: _futureBuilderFuture,
|
||||||
children: [
|
builder: (context, snapshot) {
|
||||||
const SizedBox(width: 20),
|
if (snapshot.connectionState == ConnectionState.done) {
|
||||||
FutureBuilder(
|
Map data = snapshot.data;
|
||||||
future: _futureBuilderFuture,
|
if (data['status']) {
|
||||||
builder: (context, snapshot) {
|
List favFolderList =
|
||||||
if (snapshot.connectionState == ConnectionState.done) {
|
_mediaController.favFolderData.value.list!;
|
||||||
Map data = snapshot.data;
|
int favFolderCount =
|
||||||
if (data['status']) {
|
_mediaController.favFolderData.value.count!;
|
||||||
return Obx(() => Row(
|
bool flag = favFolderCount > favFolderList.length;
|
||||||
children: [
|
return Obx(() => ListView.builder(
|
||||||
if (_mediaController.favFolderData.value.list !=
|
itemCount: _mediaController
|
||||||
null) ...[
|
.favFolderData.value.list!.length +
|
||||||
for (FavFolderItemData i in _mediaController
|
(flag ? 1 : 0),
|
||||||
.favFolderData.value.list!) ...[
|
itemBuilder: (context, index) {
|
||||||
FavFolderItem(item: i),
|
if (flag && index == favFolderList.length) {
|
||||||
const SizedBox(width: 14)
|
return Padding(
|
||||||
]
|
padding: const EdgeInsets.only(
|
||||||
]
|
right: 14, bottom: 35),
|
||||||
],
|
child: Center(
|
||||||
));
|
child: IconButton(
|
||||||
} else {
|
onPressed: () => Get.toNamed('/fav'),
|
||||||
return SizedBox(
|
icon: Icon(
|
||||||
height: 160,
|
Icons.arrow_forward_ios,
|
||||||
child: Center(child: Text(data['msg'])),
|
size: 18,
|
||||||
);
|
color: Theme.of(context).primaryColor,
|
||||||
}
|
),
|
||||||
} else {
|
),
|
||||||
// 骨架屏
|
));
|
||||||
return SizedBox();
|
} else {
|
||||||
}
|
return FavFolderItem(
|
||||||
}),
|
item: _mediaController
|
||||||
// for (var i in [1, 2, 3]) ...[const FavFolderItem()],
|
.favFolderData.value.list![index],
|
||||||
const SizedBox(width: 10)
|
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 {
|
class FavFolderItem extends StatelessWidget {
|
||||||
FavFolderItem({super.key, this.item});
|
FavFolderItem({super.key, this.item, this.index});
|
||||||
FavFolderItemData? item;
|
FavFolderItemData? item;
|
||||||
|
int? index;
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return GestureDetector(
|
return Container(
|
||||||
onTap: () => Get.toNamed('/favDetail', arguments: item, parameters: {
|
margin: EdgeInsets.only(left: index == 0 ? 20 : 0, right: 14),
|
||||||
'mediaId': item!.id.toString(),
|
child: GestureDetector(
|
||||||
}),
|
onTap: () => Get.toNamed('/favDetail', arguments: item, parameters: {
|
||||||
child: Column(
|
'mediaId': item!.id.toString(),
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
}),
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
child: Column(
|
||||||
children: [
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
const SizedBox(height: 12),
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
Container(
|
children: [
|
||||||
width: 180,
|
const SizedBox(height: 12),
|
||||||
height: 110,
|
Container(
|
||||||
margin: const EdgeInsets.only(bottom: 8),
|
width: 180,
|
||||||
clipBehavior: Clip.hardEdge,
|
height: 110,
|
||||||
decoration: BoxDecoration(
|
margin: const EdgeInsets.only(bottom: 8),
|
||||||
borderRadius: BorderRadius.circular(12),
|
clipBehavior: Clip.hardEdge,
|
||||||
color: Theme.of(context).colorScheme.onInverseSurface,
|
decoration: BoxDecoration(
|
||||||
boxShadow: [
|
borderRadius: BorderRadius.circular(12),
|
||||||
BoxShadow(
|
color: Theme.of(context).colorScheme.onInverseSurface,
|
||||||
color: Theme.of(context).colorScheme.onInverseSurface,
|
boxShadow: [
|
||||||
offset: const Offset(4, -12), // 阴影与容器的距离
|
BoxShadow(
|
||||||
blurRadius: 0.0, // 高斯的标准偏差与盒子的形状卷积。
|
color: Theme.of(context).colorScheme.onInverseSurface,
|
||||||
spreadRadius: 0.0, // 在应用模糊之前,框应该膨胀的量。
|
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(
|
Text(
|
||||||
builder: (context, BoxConstraints box) {
|
' ${item!.title}',
|
||||||
return NetworkImgLayer(
|
overflow: TextOverflow.fade,
|
||||||
src: item!.cover,
|
maxLines: 1,
|
||||||
width: box.maxWidth,
|
|
||||||
height: box.maxHeight,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
),
|
Text(
|
||||||
Text(
|
' 共${item!.mediaCount}条视频',
|
||||||
' ${item!.title}',
|
style: Theme.of(context)
|
||||||
overflow: TextOverflow.fade,
|
.textTheme
|
||||||
maxLines: 1,
|
.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 {
|
Future queryUserInfo() async {
|
||||||
|
if (user.get(UserBoxKey.userLogin) == null) {
|
||||||
|
return {'status': false};
|
||||||
|
}
|
||||||
var res = await UserHttp.userInfo();
|
var res = await UserHttp.userInfo();
|
||||||
if (res['status']) {
|
if (res['status']) {
|
||||||
if (res['data'].isLogin) {
|
if (res['data'].isLogin) {
|
||||||
|
@ -64,6 +64,7 @@ class _MinePageState extends State<MinePage> {
|
|||||||
future: _mineController.queryUserInfo(),
|
future: _mineController.queryUserInfo(),
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
if (snapshot.connectionState == ConnectionState.done) {
|
if (snapshot.connectionState == ConnectionState.done) {
|
||||||
|
print(snapshot.data);
|
||||||
if (snapshot.data['status']) {
|
if (snapshot.data['status']) {
|
||||||
return Obx(() => userInfoBuild());
|
return Obx(() => userInfoBuild());
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
import 'package:hive/hive.dart';
|
||||||
import 'package:pilipala/http/user.dart';
|
import 'package:pilipala/http/user.dart';
|
||||||
import 'package:pilipala/http/video.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/models/video_detail_res.dart';
|
||||||
import 'package:pilipala/pages/video/detail/controller.dart';
|
import 'package:pilipala/pages/video/detail/controller.dart';
|
||||||
|
import 'package:pilipala/utils/storage.dart';
|
||||||
|
|
||||||
class VideoIntroController extends GetxController {
|
class VideoIntroController extends GetxController {
|
||||||
// 视频aid
|
// 视频aid
|
||||||
@ -34,6 +37,11 @@ class VideoIntroController extends GetxController {
|
|||||||
RxBool hasCoin = false.obs;
|
RxBool hasCoin = false.obs;
|
||||||
// 是否收藏
|
// 是否收藏
|
||||||
RxBool hasFav = false.obs;
|
RxBool hasFav = false.obs;
|
||||||
|
Box user = GStrorage.user;
|
||||||
|
bool userLogin = false;
|
||||||
|
Rx<FavFolderData> favFolderData = FavFolderData().obs;
|
||||||
|
List addMediaIdsNew = [];
|
||||||
|
List delMediaIdsNew = [];
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onInit() {
|
void onInit() {
|
||||||
@ -51,6 +59,7 @@ class VideoIntroController extends GetxController {
|
|||||||
videoItem!['owner'] = args.owner;
|
videoItem!['owner'] = args.owner;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
userLogin = user.get(UserBoxKey.userLogin) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取视频简介
|
// 获取视频简介
|
||||||
@ -66,12 +75,14 @@ class VideoIntroController extends GetxController {
|
|||||||
}
|
}
|
||||||
// 获取到粉丝数再返回
|
// 获取到粉丝数再返回
|
||||||
await queryUserStat();
|
await queryUserStat();
|
||||||
// 获取点赞状态
|
if (userLogin) {
|
||||||
queryHasLikeVideo();
|
// 获取点赞状态
|
||||||
// 获取投币状态
|
queryHasLikeVideo();
|
||||||
queryHasCoinVideo();
|
// 获取投币状态
|
||||||
// 获取收藏状态
|
queryHasCoinVideo();
|
||||||
queryHasFavVideo();
|
// 获取收藏状态
|
||||||
|
queryHasFavVideo();
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
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 {
|
Future actionLikeVideo() async {
|
||||||
var result = await VideoHttp.likeVideo(aid: aid, type: !hasLike.value);
|
var result = await VideoHttp.likeVideo(aid: aid, type: !hasLike.value);
|
||||||
if (result['status']) {
|
if (result['status']) {
|
||||||
hasLike.value = result["data"] == 1 ? true : false;
|
hasLike.value = result["data"] == 1 ? true : false;
|
||||||
|
if (hasLike.value) {
|
||||||
|
SmartDialog.showToast('已点赞 👍');
|
||||||
|
} else {
|
||||||
|
SmartDialog.showToast('取消赞');
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
SmartDialog.showToast(result['msg']);
|
SmartDialog.showToast(result['msg']);
|
||||||
}
|
}
|
||||||
@ -122,12 +175,58 @@ class VideoIntroController extends GetxController {
|
|||||||
|
|
||||||
// (取消)收藏
|
// (取消)收藏
|
||||||
Future actionFavVideo() async {
|
Future actionFavVideo() async {
|
||||||
print('(取消)收藏');
|
try {
|
||||||
// var result = await VideoHttp.favVideo(aid: aid, type: true, ids: '');
|
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 {
|
Future actionShareVideo() async {
|
||||||
print('分享视频');
|
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']) {
|
if (snapshot.data['status']) {
|
||||||
// 请求成功
|
// 请求成功
|
||||||
// return _buildView(context, false, videoDetail);
|
// return _buildView(context, false, videoDetail);
|
||||||
return VideoInfo(
|
return VideoInfo(loadingStatus: false, videoDetail: videoDetail);
|
||||||
loadingStatus: false,
|
|
||||||
videoDetail: videoDetail,
|
|
||||||
videoIntroController: videoIntroController);
|
|
||||||
} else {
|
} else {
|
||||||
// 请求错误
|
// 请求错误
|
||||||
return HttpError(
|
return HttpError(
|
||||||
@ -66,10 +63,7 @@ class _VideoIntroPanelState extends State<VideoIntroPanel>
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return VideoInfo(
|
return VideoInfo(loadingStatus: true, videoDetail: videoDetail);
|
||||||
loadingStatus: true,
|
|
||||||
videoDetail: videoDetail,
|
|
||||||
videoIntroController: videoIntroController);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -79,13 +73,8 @@ class _VideoIntroPanelState extends State<VideoIntroPanel>
|
|||||||
class VideoInfo extends StatefulWidget {
|
class VideoInfo extends StatefulWidget {
|
||||||
bool loadingStatus = false;
|
bool loadingStatus = false;
|
||||||
VideoDetailData? videoDetail;
|
VideoDetailData? videoDetail;
|
||||||
VideoIntroController? videoIntroController;
|
|
||||||
|
|
||||||
VideoInfo(
|
VideoInfo({Key? key, required this.loadingStatus, this.videoDetail})
|
||||||
{Key? key,
|
|
||||||
required this.loadingStatus,
|
|
||||||
this.videoDetail,
|
|
||||||
this.videoIntroController})
|
|
||||||
: super(key: key);
|
: super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -94,6 +83,8 @@ class VideoInfo extends StatefulWidget {
|
|||||||
|
|
||||||
class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
||||||
Map videoItem = Get.put(VideoIntroController()).videoItem!;
|
Map videoItem = Get.put(VideoIntroController()).videoItem!;
|
||||||
|
final VideoIntroController videoIntroController =
|
||||||
|
Get.put(VideoIntroController(), tag: Get.arguments['heroTag']);
|
||||||
bool isExpand = false;
|
bool isExpand = false;
|
||||||
|
|
||||||
/// 手动控制动画的控制器
|
/// 手动控制动画的控制器
|
||||||
@ -137,7 +128,7 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
|||||||
),
|
),
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Get.back(),
|
onPressed: () => videoIntroController.actionFavVideo(),
|
||||||
child: const Text('完成'),
|
child: const Text('完成'),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 6),
|
const SizedBox(width: 6),
|
||||||
@ -146,30 +137,34 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: Material(
|
child: Material(
|
||||||
child: FutureBuilder(
|
child: FutureBuilder(
|
||||||
future: _favController.queryFavFolder(),
|
future: videoIntroController.queryVideoInFolder(),
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
if (snapshot.connectionState == ConnectionState.done) {
|
if (snapshot.connectionState == ConnectionState.done) {
|
||||||
Map data = snapshot.data as Map;
|
Map data = snapshot.data as Map;
|
||||||
if (data['status']) {
|
if (data['status']) {
|
||||||
return Obx(
|
return Obx(
|
||||||
() => ListView.builder(
|
() => ListView.builder(
|
||||||
itemCount: _favController
|
itemCount: videoIntroController
|
||||||
.favFolderData.value.list!.length +
|
.favFolderData.value.list!.length +
|
||||||
1,
|
1,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
if (index == 0) {
|
if (index == 0) {
|
||||||
return const SizedBox(height: 15);
|
return const SizedBox(height: 10);
|
||||||
} else {
|
} else {
|
||||||
return ListTile(
|
return ListTile(
|
||||||
onTap: () {},
|
onTap: () => videoIntroController.onChoose(
|
||||||
|
videoIntroController.favFolderData.value
|
||||||
|
.list![index - 1].favState !=
|
||||||
|
1,
|
||||||
|
index - 1),
|
||||||
dense: true,
|
dense: true,
|
||||||
leading:
|
leading:
|
||||||
const Icon(Icons.folder_special_outlined),
|
const Icon(Icons.folder_special_outlined),
|
||||||
minLeadingWidth: 0,
|
minLeadingWidth: 0,
|
||||||
title: Text(_favController.favFolderData.value
|
title: Text(videoIntroController.favFolderData
|
||||||
.list![index - 1].title!),
|
.value.list![index - 1].title!),
|
||||||
subtitle: Text(
|
subtitle: Text(
|
||||||
'${_favController.favFolderData.value.list![index - 1].mediaCount}个内容',
|
'${videoIntroController.favFolderData.value.list![index - 1].mediaCount}个内容',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Theme.of(context)
|
color: Theme.of(context)
|
||||||
.colorScheme
|
.colorScheme
|
||||||
@ -182,8 +177,15 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
|||||||
trailing: Transform.scale(
|
trailing: Transform.scale(
|
||||||
scale: 0.9,
|
scale: 0.9,
|
||||||
child: Checkbox(
|
child: Checkbox(
|
||||||
value: false,
|
value: videoIntroController
|
||||||
onChanged: (bool? checkValue) {},
|
.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)
|
if (!widget.loadingStatus)
|
||||||
ExpandedSection(
|
ExpandedSection(
|
||||||
@ -392,8 +335,64 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 5),
|
const SizedBox(height: 8),
|
||||||
_actionGrid(context, widget.videoIntroController),
|
_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()),
|
: const Center(child: CircularProgressIndicator()),
|
||||||
@ -412,6 +411,29 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
|||||||
crossAxisCount: 5,
|
crossAxisCount: 5,
|
||||||
childAspectRatio: 1.25,
|
childAspectRatio: 1.25,
|
||||||
children: <Widget>[
|
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(
|
Obx(
|
||||||
() => ActionItem(
|
() => ActionItem(
|
||||||
icon: const Icon(FontAwesomeIcons.thumbsUp),
|
icon: const Icon(FontAwesomeIcons.thumbsUp),
|
||||||
@ -423,13 +445,13 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
|||||||
? widget.videoDetail!.stat!.like!.toString()
|
? widget.videoDetail!.stat!.like!.toString()
|
||||||
: '-'),
|
: '-'),
|
||||||
),
|
),
|
||||||
ActionItem(
|
// ActionItem(
|
||||||
icon: const Icon(FontAwesomeIcons.thumbsDown),
|
// icon: const Icon(FontAwesomeIcons.thumbsDown),
|
||||||
selectIcon: const Icon(FontAwesomeIcons.solidThumbsDown),
|
// selectIcon: const Icon(FontAwesomeIcons.solidThumbsDown),
|
||||||
onTap: () => {},
|
// onTap: () => {},
|
||||||
selectStatus: false,
|
// selectStatus: false,
|
||||||
loadingStatus: widget.loadingStatus,
|
// loadingStatus: widget.loadingStatus,
|
||||||
text: '不喜欢'),
|
// text: '不喜欢'),
|
||||||
Obx(
|
Obx(
|
||||||
() => ActionItem(
|
() => ActionItem(
|
||||||
icon: const Icon(FontAwesomeIcons.b),
|
icon: const Icon(FontAwesomeIcons.b),
|
||||||
@ -445,7 +467,6 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
|||||||
() => ActionItem(
|
() => ActionItem(
|
||||||
icon: const Icon(FontAwesomeIcons.star),
|
icon: const Icon(FontAwesomeIcons.star),
|
||||||
selectIcon: const Icon(FontAwesomeIcons.star),
|
selectIcon: const Icon(FontAwesomeIcons.star),
|
||||||
// onTap: () => videoIntroController.actionFavVideo(),
|
|
||||||
onTap: () => showFavBottomSheet(),
|
onTap: () => showFavBottomSheet(),
|
||||||
selectStatus: videoIntroController.hasFav.value,
|
selectStatus: videoIntroController.hasFav.value,
|
||||||
loadingStatus: widget.loadingStatus,
|
loadingStatus: widget.loadingStatus,
|
||||||
@ -488,37 +509,32 @@ class ActionItem extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Material(
|
return InkWell(
|
||||||
child: Ink(
|
onTap: () => onTap!(),
|
||||||
child: InkWell(
|
borderRadius: StyleString.mdRadius,
|
||||||
onTap: () => onTap!(),
|
child: Column(
|
||||||
borderRadius: StyleString.mdRadius,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
child: Column(
|
children: [
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
const SizedBox(height: 4),
|
||||||
children: [
|
selectStatus
|
||||||
const SizedBox(height: 4),
|
? Icon(selectIcon!.icon!,
|
||||||
selectStatus
|
size: 21, color: Theme.of(context).primaryColor)
|
||||||
? Icon(selectIcon!.icon!,
|
: Icon(icon!.icon!,
|
||||||
size: 21, color: Theme.of(context).primaryColor)
|
size: 21, color: Theme.of(context).colorScheme.outline),
|
||||||
: Icon(icon!.icon!,
|
const SizedBox(height: 4),
|
||||||
size: 21, color: Theme.of(context).colorScheme.outline),
|
AnimatedOpacity(
|
||||||
const SizedBox(height: 4),
|
opacity: loadingStatus! ? 0 : 1,
|
||||||
AnimatedOpacity(
|
duration: const Duration(milliseconds: 200),
|
||||||
opacity: loadingStatus! ? 0 : 1,
|
child: Text(
|
||||||
duration: const Duration(milliseconds: 200),
|
text ?? '',
|
||||||
child: Text(
|
style: TextStyle(
|
||||||
text!,
|
color: selectStatus
|
||||||
style: TextStyle(
|
? Theme.of(context).primaryColor
|
||||||
color: selectStatus
|
: Theme.of(context).colorScheme.outline,
|
||||||
? Theme.of(context).primaryColor
|
fontSize: Theme.of(context).textTheme.labelSmall?.fontSize),
|
||||||
: Theme.of(context).colorScheme.outline,
|
),
|
||||||
fontSize:
|
|
||||||
Theme.of(context).textTheme.labelSmall?.fontSize),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -114,23 +114,11 @@ class _VideoDetailPageState extends State<VideoDetailPage> {
|
|||||||
children: [
|
children: [
|
||||||
Builder(
|
Builder(
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
return CustomScrollView(
|
return const CustomScrollView(
|
||||||
key: const PageStorageKey<String>('简介'),
|
key: PageStorageKey<String>('简介'),
|
||||||
slivers: <Widget>[
|
slivers: <Widget>[
|
||||||
const VideoIntroPanel(),
|
VideoIntroPanel(),
|
||||||
SliverPadding(
|
RelatedVideoPanel(),
|
||||||
padding:
|
|
||||||
const EdgeInsets.only(top: 8, bottom: 5),
|
|
||||||
sliver: SliverToBoxAdapter(
|
|
||||||
child: Divider(
|
|
||||||
height: 1,
|
|
||||||
color: Theme.of(context)
|
|
||||||
.dividerColor
|
|
||||||
.withOpacity(0.1),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const RelatedVideoPanel(),
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
import 'package:hive/hive.dart';
|
||||||
import 'package:pilipala/http/constants.dart';
|
import 'package:pilipala/http/constants.dart';
|
||||||
import 'package:pilipala/http/init.dart';
|
import 'package:pilipala/http/init.dart';
|
||||||
import 'package:pilipala/http/user.dart';
|
import 'package:pilipala/http/user.dart';
|
||||||
|
import 'package:pilipala/pages/home/index.dart';
|
||||||
import 'package:pilipala/pages/mine/index.dart';
|
import 'package:pilipala/pages/mine/index.dart';
|
||||||
import 'package:pilipala/utils/cookie.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_cookie_manager/webview_cookie_manager.dart';
|
||||||
import 'package:webview_flutter/webview_flutter.dart';
|
import 'package:webview_flutter/webview_flutter.dart';
|
||||||
|
|
||||||
@ -52,10 +55,15 @@ class WebviewController extends GetxController {
|
|||||||
await WebviewCookieManager().getCookies(HttpString.baseUrl);
|
await WebviewCookieManager().getCookies(HttpString.baseUrl);
|
||||||
await SetCookie.onSet(cookies, HttpString.baseUrl);
|
await SetCookie.onSet(cookies, HttpString.baseUrl);
|
||||||
await SetCookie.onSet(apiCookies, HttpString.baseApiUrl);
|
await SetCookie.onSet(apiCookies, HttpString.baseApiUrl);
|
||||||
|
await UserHttp.userInfo();
|
||||||
var result = await UserHttp.userInfo();
|
var result = await UserHttp.userInfo();
|
||||||
|
print('网页登录: $result');
|
||||||
if (result['status'] && result['data'].isLogin) {
|
if (result['status'] && result['data'].isLogin) {
|
||||||
SmartDialog.showToast('登录成功');
|
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();
|
Get.back();
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -113,6 +113,7 @@ flutter:
|
|||||||
assets:
|
assets:
|
||||||
- assets/images/
|
- assets/images/
|
||||||
- assets/images/lv/
|
- assets/images/lv/
|
||||||
|
- assets/images/logo/
|
||||||
# An image asset can refer to one or more resolution-specific "variants", see
|
# An image asset can refer to one or more resolution-specific "variants", see
|
||||||
# https://flutter.dev/assets-and-images/#resolution-aware
|
# https://flutter.dev/assets-and-images/#resolution-aware
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user