Merge branch 'main' into design

This commit is contained in:
guozhigq
2024-10-07 23:26:39 +08:00
16 changed files with 292 additions and 284 deletions

View File

@ -592,4 +592,7 @@ class Api {
/// 直播间记录
static const String liveRoomEntry =
'${HttpString.liveBaseUrl}/xlive/web-room/v1/index/roomEntryAction';
/// 删除评论
static const String replyDel = '/x/v2/reply/del';
}

View File

@ -229,12 +229,25 @@ class LoginHttp {
data: formData,
);
if (res.data['code'] == 0) {
return {
'status': true,
'data': res.data['data'],
};
if (res.data['data']['status'] == 0) {
return {
'status': true,
'data': res.data['data'],
};
} else {
return {
'status': false,
'code': 1,
'data': res.data['data'],
'msg': res.data['data']['message'],
};
}
} else {
return {'status': false, 'data': [], 'msg': res.data['message']};
return {
'status': false,
'data': [],
'msg': res.data['message'],
};
}
}

View File

@ -115,4 +115,25 @@ class ReplyHttp {
};
}
}
static Future replyDel({
required int type, //replyType
required int oid,
required int rpid,
}) async {
var res = await Request().post(
Api.replyDel,
queryParameters: {
'type': type, //type.index
'oid': oid,
'rpid': rpid,
'csrf': await Request.getCsrf(),
},
);
if (res.data['code'] == 0) {
return {'status': true, 'msg': '删除成功'};
} else {
return {'status': false, 'msg': res.data['message']};
}
}
}

View File

@ -79,56 +79,68 @@ class _FavPageState extends State<FavPage> {
const SizedBox(width: 14),
],
),
body: FutureBuilder(
future: _futureBuilderFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
Map? data = snapshot.data;
if (data != null && data['status']) {
return Obx(
() => ListView.builder(
controller: scrollController,
itemCount: _favController.favFolderList.length,
itemBuilder: (context, index) {
return FavItem(
favFolderItem: _favController.favFolderList[index],
isOwner: _favController.isOwner.value,
);
},
),
);
} else {
return CustomScrollView(
physics: const NeverScrollableScrollPhysics(),
slivers: [
HttpError(
errMsg: data?['msg'] ?? '请求异常',
btnText: data?['code'] == -101 ? '去登录' : null,
fn: () {
if (data?['code'] == -101) {
RoutePush.loginRedirectPush();
} else {
setState(() {
_futureBuilderFuture =
_favController.queryFavFolder();
});
}
},
),
],
);
}
} else {
// 骨架屏
return ListView.builder(
itemBuilder: (context, index) {
return const VideoCardHSkeleton();
},
itemCount: 10,
);
}
body: RefreshIndicator(
onRefresh: () async {
_favController.hasMore.value = true;
_favController.currentPage = 1;
setState(() {
_futureBuilderFuture = _favController.queryFavFolder(type: 'init');
});
},
child: _buildBody(),
),
);
}
Widget _buildBody() {
return FutureBuilder(
future: _futureBuilderFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
Map? data = snapshot.data;
if (data != null && data['status']) {
return Obx(
() => ListView.builder(
controller: scrollController,
itemCount: _favController.favFolderList.length,
itemBuilder: (context, index) {
return FavItem(
favFolderItem: _favController.favFolderList[index],
isOwner: _favController.isOwner.value,
);
},
),
);
} else {
return CustomScrollView(
physics: const NeverScrollableScrollPhysics(),
slivers: [
HttpError(
errMsg: data?['msg'] ?? '请求异常',
btnText: data?['code'] == -101 ? '去登录' : null,
fn: () {
if (data?['code'] == -101) {
RoutePush.loginRedirectPush();
} else {
setState(() {
_futureBuilderFuture = _favController.queryFavFolder();
});
}
},
),
],
);
}
} else {
// 骨架屏
return ListView.builder(
itemBuilder: (context, index) {
return const VideoCardHSkeleton();
},
itemCount: 10,
);
}
},
);
}
}

View File

@ -10,6 +10,7 @@ import 'package:pilipala/utils/utils.dart';
class FavDetailController extends GetxController {
FavFolderItemData? item;
RxString title = ''.obs;
int? mediaId;
late String heroTag;
@ -24,6 +25,7 @@ class FavDetailController extends GetxController {
@override
void onInit() {
item = Get.arguments;
title.value = item!.title!;
if (Get.parameters.keys.isNotEmpty) {
mediaId = int.parse(Get.parameters['mediaId']!);
heroTag = Get.parameters['heroTag']!;
@ -117,16 +119,18 @@ class FavDetailController extends GetxController {
}
onEditFavFolder() async {
Get.toNamed(
var res = await Get.toNamed(
'/favEdit',
arguments: {
'mediaId': mediaId.toString(),
'title': item!.title,
'intro': item!.intro,
'cover': item!.cover,
'privacy': item!.attr,
'privacy': [23, 1].contains(item!.attr) ? 1 : 0,
},
);
title.value = res['title'];
print(title);
}
Future toViewPlayAll() async {

View File

@ -80,9 +80,11 @@ class _FavDetailPageState extends State<FavDetailPage> {
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
_favDetailController.item!.title!,
style: Theme.of(context).textTheme.titleMedium,
Obx(
() => Text(
_favDetailController.title.value,
style: Theme.of(context).textTheme.titleMedium,
),
),
Text(
'${_favDetailController.mediaCount}条视频',
@ -156,14 +158,16 @@ class _FavDetailPageState extends State<FavDetailPage> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 4),
Text(
_favDetailController.item!.title!,
style: TextStyle(
fontSize: Theme.of(context)
.textTheme
.titleMedium!
.fontSize,
fontWeight: FontWeight.bold),
Obx(
() => Text(
_favDetailController.title.value,
style: TextStyle(
fontSize: Theme.of(context)
.textTheme
.titleMedium!
.fontSize,
fontWeight: FontWeight.bold),
),
),
const SizedBox(height: 4),
Text(

View File

@ -56,7 +56,7 @@ class FavEditController extends GetxController {
);
if (res['status']) {
SmartDialog.showToast('编辑成功');
Get.back();
Get.back(result: {'title': title});
} else {
SmartDialog.showToast(res['msg']);
}

View File

@ -45,6 +45,7 @@ class LoginPageController extends GetxController {
RxInt validSeconds = 180.obs;
Timer? validTimer;
late String qrcodeKey;
RxBool passwordVisible = false.obs;
// 监听pageView切换
void onPageChange(int index) {
@ -128,7 +129,14 @@ class LoginPageController extends GetxController {
if (res['status']) {
await LoginUtils.confirmLogin('', null);
} else {
SmartDialog.showToast(res['msg']);
await SmartDialog.showToast(res['msg']);
if (res.containsKey('code') && res['code'] == 1) {
Get.toNamed('/webview', parameters: {
'url': res['data']['data']['url'],
'type': 'url',
'pageTitle': '登录验证',
});
}
}
} else {
SmartDialog.showToast(webKeyRes['msg']);

View File

@ -269,25 +269,46 @@ class _LoginPageState extends State<LoginPage> {
),
Container(
margin: const EdgeInsets.only(top: 38, bottom: 15),
child: TextFormField(
controller: _loginPageCtr.passwordTextController,
focusNode: _loginPageCtr.passwordTextFieldNode,
keyboardType: TextInputType.visiblePassword,
decoration: InputDecoration(
isDense: true,
labelText: '输入密码',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(6.0),
),
),
// 校验用户名
validator: (v) {
return v!.trim().isNotEmpty ? null : "密码不能为空";
},
onSaved: (val) {
print(val);
},
),
child: Obx(() => TextFormField(
controller:
_loginPageCtr.passwordTextController,
focusNode:
_loginPageCtr.passwordTextFieldNode,
keyboardType: TextInputType.visiblePassword,
obscureText:
_loginPageCtr.passwordVisible.value,
decoration: InputDecoration(
isDense: true,
labelText: '输入密码',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(6.0),
),
suffixIcon: IconButton(
icon: Icon(
_loginPageCtr.passwordVisible.value
? Icons.visibility
: Icons.visibility_off,
color: Theme.of(context)
.colorScheme
.primary,
),
onPressed: () {
_loginPageCtr.passwordVisible.value =
!_loginPageCtr
.passwordVisible.value;
},
),
),
// 校验用户名
validator: (v) {
return v!.trim().isNotEmpty
? null
: "密码不能为空";
},
onSaved: (val) {
print(val);
},
)),
),
const Spacer(),
Row(

View File

@ -157,7 +157,7 @@ class _OpusPageState extends State<OpusPage> {
Container(
alignment: TextHelper.getAlignment(paragraph.align),
margin: const EdgeInsets.only(bottom: 10),
child: Text.rich(
child: SelectableText.rich(
TextSpan(
children: paragraph.text?.nodes?.map((node) {
return TextHelper.buildTextSpan(

View File

@ -20,7 +20,7 @@ class ReadPageController extends GetxController {
super.onInit();
title.value = Get.parameters['title'] ?? '';
id = Get.parameters['id']!;
articleType = Get.parameters['articleType']!;
articleType = Get.parameters['articleType'] ?? 'read';
url = 'https://www.bilibili.com/read/cv$id';
scrollController.addListener(_scrollListener);
fetchViewInfo();

View File

@ -126,7 +126,6 @@ class _ReadPageState extends State<ReadPage> {
Widget _buildContent(ReadDataModel cvData) {
final List<String> picList = _extractPicList(cvData);
final List<String> imgList = extractDataSrc(cvData.readInfo!.content!);
return Padding(
padding: EdgeInsets.fromLTRB(
16, 0, 16, MediaQuery.of(context).padding.bottom + 40),
@ -163,9 +162,11 @@ class _ReadPageState extends State<ReadPage> {
padding: const EdgeInsets.only(bottom: 20),
child: _buildAuthorWidget(cvData),
),
HtmlRender(
htmlContent: cvData.readInfo!.content!,
imgList: imgList,
SelectionArea(
child: HtmlRender(
htmlContent: cvData.readInfo!.content!,
imgList: imgList,
),
),
],
);
@ -206,7 +207,7 @@ class _ReadPageState extends State<ReadPage> {
return Container(
alignment: TextHelper.getAlignment(paragraph.align),
margin: const EdgeInsets.only(bottom: 10),
child: Text.rich(
child: SelectableText.rich(
TextSpan(
children: paragraph.text?.nodes?.map((node) {
return TextHelper.buildTextSpan(node, paragraph.align, context);

View File

@ -3,7 +3,6 @@ import 'dart:async';
import 'package:bottom_sheet/bottom_sheet.dart';
import 'package:flutter/material.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:get/get.dart';
import 'package:hive/hive.dart';
import 'package:pilipala/http/constants.dart';
@ -154,11 +153,10 @@ class VideoIntroController extends GetxController {
}
if (hasLike.value && hasCoin.value && hasFav.value) {
// 已点赞、投币、收藏
SmartDialog.showToast('🙏 UP已经收到了');
SmartDialog.showToast('UP已经收到了');
return false;
}
var result = await VideoHttp.oneThree(bvid: bvid);
print('🤣🦴:${result["data"]}');
if (result['status']) {
hasLike.value = result["data"]["like"];
hasCoin.value = result["data"]["coin"];
@ -604,4 +602,34 @@ class VideoIntroController extends GetxController {
).buildShowContent(Get.context!),
);
}
//
oneThreeDialog() {
showDialog(
context: Get.context!,
builder: (context) {
return AlertDialog(
title: const Text('提示'),
content: const Text('是否一键三连'),
actions: [
TextButton(
onPressed: () => navigator!.pop(),
child: Text(
'取消',
style: TextStyle(
color: Theme.of(Get.context!).colorScheme.outline),
),
),
TextButton(
onPressed: () async {
actionOneThree();
navigator!.pop();
},
child: const Text('确认'),
)
],
);
},
);
}
}

View File

@ -1,7 +1,4 @@
import 'dart:ffi';
import 'package:bottom_sheet/bottom_sheet.dart';
import 'package:easy_debounce/easy_throttle.dart';
import 'package:expandable/expandable.dart';
import 'package:flutter/services.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
@ -151,11 +148,6 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
RxBool isExpand = false.obs;
late ExpandableController _expandableCtr;
// 一键三连动画
late AnimationController _controller;
late Animation<double> _scaleTransition;
final RxDouble _progress = 0.0.obs;
void Function()? handleState(Future<dynamic> Function() action) {
return isProcessing
? null
@ -178,26 +170,6 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
owner = widget.videoDetail!.owner;
enableAi = setting.get(SettingBoxKey.enableAi, defaultValue: true);
_expandableCtr = ExpandableController(initialExpanded: false);
/// 一键三连动画
_controller = AnimationController(
duration: const Duration(milliseconds: 1500),
reverseDuration: const Duration(milliseconds: 300),
vsync: this,
);
_scaleTransition = Tween<double>(begin: 0.5, end: 1.5).animate(_controller)
..addListener(() async {
_progress.value =
double.parse((_scaleTransition.value - 0.5).toStringAsFixed(3));
if (_progress.value == 1) {
if (_controller.status == AnimationStatus.completed) {
await videoIntroController.actionOneThree();
}
_progress.value = 0;
_scaleTransition.removeListener(() {});
_controller.stop();
}
});
}
// 收藏
@ -279,8 +251,6 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
@override
void dispose() {
_expandableCtr.dispose();
_controller.dispose();
_scaleTransition.removeListener(() {});
super.dispose();
}
@ -573,131 +543,34 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
Widget actionGrid(BuildContext context, videoIntroController) {
final actionTypeSort = GlobalDataCache().actionTypeSort;
Widget progressWidget(progress) {
return SizedBox(
width: const IconThemeData.fallback().size! + 5,
height: const IconThemeData.fallback().size! + 5,
child: CircularProgressIndicator(
value: progress.value,
strokeWidth: 2,
),
);
}
Map<String, Widget> menuListWidgets = {
'like': Obx(
() {
bool likeStatus = videoIntroController.hasLike.value;
ColorScheme colorScheme = Theme.of(context).colorScheme;
return Stack(
children: [
Positioned(
top: ((Get.size.width - 24) / 5) / 2 -
(const IconThemeData.fallback().size!),
left: ((Get.size.width - 24) / 5) / 2 -
(const IconThemeData.fallback().size! + 5) / 2,
child: progressWidget(_progress)),
InkWell(
onTapDown: (details) {
feedBack();
if (videoIntroController.userInfo == null) {
SmartDialog.showToast('账号未登录');
return;
}
_controller.forward();
},
onTapUp: (TapUpDetails details) {
if (_progress.value == 0) {
feedBack();
EasyThrottle.throttle(
'my-throttler', const Duration(milliseconds: 200), () {
videoIntroController.actionLikeVideo();
});
}
_controller.reverse();
},
onTapCancel: () {
_controller.reverse();
},
borderRadius: StyleString.mdRadius,
child: SizedBox(
width: (Get.size.width - 24) / 5,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const SizedBox(height: 4),
AnimatedSwitcher(
duration: const Duration(milliseconds: 300),
transitionBuilder:
(Widget child, Animation<double> animation) {
return ScaleTransition(
scale: animation, child: child);
},
child: Icon(
key: ValueKey<bool>(likeStatus),
likeStatus
? FontAwesomeIcons.solidThumbsUp
: FontAwesomeIcons.thumbsUp,
color: likeStatus
? colorScheme.primary
: colorScheme.outline,
size: 21,
),
),
const SizedBox(height: 6),
Text(
widget.videoDetail!.stat!.like!.toString(),
style: TextStyle(
color: likeStatus ? colorScheme.primary : null,
fontSize:
Theme.of(context).textTheme.labelSmall!.fontSize,
),
)
],
),
),
),
],
);
},
() => ActionItem(
icon: const Icon(FontAwesomeIcons.thumbsUp),
selectIcon: const Icon(FontAwesomeIcons.solidThumbsUp),
onTap: handleState(videoIntroController.actionLikeVideo),
onLongPress: () => videoIntroController.oneThreeDialog(),
selectStatus: videoIntroController.hasLike.value,
text: widget.videoDetail!.stat!.like!.toString(),
),
),
'coin': Obx(
() => Stack(
children: [
Positioned(
top: ((Get.size.width - 24) / 5) / 2 -
(const IconThemeData.fallback().size!),
left: ((Get.size.width - 24) / 5) / 2 -
(const IconThemeData.fallback().size! + 5) / 2,
child: progressWidget(_progress)),
ActionItem(
icon: const Icon(FontAwesomeIcons.b),
selectIcon: const Icon(FontAwesomeIcons.b),
onTap: handleState(videoIntroController.actionCoinVideo),
selectStatus: videoIntroController.hasCoin.value,
text: widget.videoDetail!.stat!.coin!.toString(),
),
],
() => ActionItem(
icon: const Icon(FontAwesomeIcons.b),
selectIcon: const Icon(FontAwesomeIcons.b),
onTap: handleState(videoIntroController.actionCoinVideo),
selectStatus: videoIntroController.hasCoin.value,
text: widget.videoDetail!.stat!.coin!.toString(),
),
),
'collect': Obx(
() => Stack(
children: [
Positioned(
top: ((Get.size.width - 24) / 5) / 2 -
(const IconThemeData.fallback().size!),
left: ((Get.size.width - 24) / 5) / 2 -
(const IconThemeData.fallback().size! + 5) / 2,
child: progressWidget(_progress)),
ActionItem(
icon: const Icon(FontAwesomeIcons.star),
selectIcon: const Icon(FontAwesomeIcons.solidStar),
onTap: () => showFavBottomSheet(),
onLongPress: () => showFavBottomSheet(type: 'longPress'),
selectStatus: videoIntroController.hasFav.value,
text: widget.videoDetail!.stat!.favorite!.toString(),
),
],
() => ActionItem(
icon: const Icon(FontAwesomeIcons.star),
selectIcon: const Icon(FontAwesomeIcons.solidStar),
onTap: () => showFavBottomSheet(),
onLongPress: () => showFavBottomSheet(type: 'longPress'),
selectStatus: videoIntroController.hasFav.value,
text: widget.videoDetail!.stat!.favorite!.toString(),
),
),
'watchLater': ActionItem(

View File

@ -9,6 +9,7 @@ import 'package:get/get.dart';
import 'package:hive/hive.dart';
import 'package:pilipala/common/widgets/badge.dart';
import 'package:pilipala/common/widgets/network_img_layer.dart';
import 'package:pilipala/http/reply.dart';
import 'package:pilipala/models/common/reply_type.dart';
import 'package:pilipala/models/video/reply/item.dart';
import 'package:pilipala/pages/main/index.dart';
@ -18,6 +19,7 @@ import 'package:pilipala/plugin/pl_gallery/index.dart';
import 'package:pilipala/plugin/pl_popup/index.dart';
import 'package:pilipala/utils/app_scheme.dart';
import 'package:pilipala/utils/feed_back.dart';
import 'package:pilipala/utils/global_data_cache.dart';
import 'package:pilipala/utils/id_utils.dart';
import 'package:pilipala/utils/storage.dart';
import 'package:pilipala/utils/url_utils.dart';
@ -48,6 +50,8 @@ class ReplyItem extends StatelessWidget {
@override
Widget build(BuildContext context) {
final bool isOwner = int.parse(replyItem!.member!.mid!) ==
(GlobalDataCache().userInfo?.mid ?? -1);
return Material(
child: InkWell(
// 点击整个评论区 评论详情/回复
@ -73,6 +77,7 @@ class ReplyItem extends StatelessWidget {
return MorePanel(
item: replyItem,
mainFloor: true,
isOwner: isOwner,
);
},
);
@ -698,14 +703,11 @@ InlineSpan buildContent(
'',
);
} else if (RegExp(r'^cv\d+$').hasMatch(matchStr)) {
Get.toNamed(
'/webview',
parameters: {
'url': 'https://www.bilibili.com/read/$matchStr',
'type': 'url',
'pageTitle': title
},
);
Get.toNamed('/read', parameters: {
'title': title,
'id': Utils.matchNum(matchStr).first.toString(),
'articleType': 'read',
});
} else {
Uri uri = Uri.parse(matchStr.replaceAll('/?', '?'));
SchemeEntity scheme = SchemeEntity(
@ -1004,10 +1006,12 @@ InlineSpan buildContent(
class MorePanel extends StatelessWidget {
final dynamic item;
final bool mainFloor;
final bool isOwner;
const MorePanel({
super.key,
required this.item,
this.mainFloor = false,
this.isOwner = false,
});
Future<dynamic> menuActionHandler(String type) async {
@ -1043,9 +1047,43 @@ class MorePanel extends StatelessWidget {
// case 'report':
// SmartDialog.showToast('举报');
// break;
// case 'delete':
// SmartDialog.showToast('删除');
// break;
case 'delete':
// 删除评论提示
await showDialog(
context: Get.context!,
builder: (context) {
return AlertDialog(
title: const Text('删除评论'),
content: const Text('删除评论后,评论下所有回复将被删除,确定删除吗?'),
actions: <Widget>[
TextButton(
onPressed: () => Get.back(),
child: Text('取消',
style: TextStyle(
color: Theme.of(context).colorScheme.outline)),
),
TextButton(
onPressed: () async {
Get.back();
var result = await ReplyHttp.replyDel(
type: item.type!,
oid: item.oid!,
rpid: item.rpid!,
);
if (result['status']) {
SmartDialog.showToast('评论删除成功,需手动刷新');
Get.back();
} else {
SmartDialog.showToast(result['msg']);
}
},
child: const Text('确定'),
),
],
);
},
);
break;
default:
}
}
@ -1054,6 +1092,7 @@ class MorePanel extends StatelessWidget {
Widget build(BuildContext context) {
ColorScheme colorScheme = Theme.of(context).colorScheme;
TextTheme textTheme = Theme.of(context).textTheme;
Color errorColor = colorScheme.error;
return Container(
padding: EdgeInsets.only(bottom: MediaQuery.of(context).padding.bottom),
child: Column(
@ -1106,12 +1145,14 @@ class MorePanel extends StatelessWidget {
// leading: Icon(Icons.report_outlined, color: errorColor),
// title: Text('举报', style: TextStyle(color: errorColor)),
// ),
// ListTile(
// onTap: () async => await menuActionHandler('del'),
// minLeadingWidth: 0,
// leading: Icon(Icons.delete_outline, color: errorColor),
// title: Text('删除', style: TextStyle(color: errorColor)),
// ),
if (isOwner)
ListTile(
onTap: () async => await menuActionHandler('delete'),
minLeadingWidth: 0,
leading: Icon(Icons.delete_outline, color: errorColor),
title: Text('删除评论',
style: textTheme.titleSmall!.copyWith(color: errorColor)),
),
],
),
);

View File

@ -68,10 +68,6 @@ class _VideoDetailPageState extends State<VideoDetailPage>
late final AppLifecycleListener _lifecycleListener;
late double statusHeight;
// 稍后再看控制器
// late AnimationController _laterCtr;
// late Animation<Offset> _laterOffsetAni;
@override
void initState() {
super.initState();
@ -108,7 +104,6 @@ class _VideoDetailPageState extends State<VideoDetailPage>
}
WidgetsBinding.instance.addObserver(this);
lifecycleListener();
// watchLaterControllerInit();
}
// 获取视频资源,初始化播放器
@ -242,8 +237,6 @@ class _VideoDetailPageState extends State<VideoDetailPage>
appbarStream.close();
WidgetsBinding.instance.removeObserver(this);
_lifecycleListener.dispose();
// _laterCtr.dispose();
// _laterOffsetAni.removeListener(() {});
super.dispose();
}
@ -297,6 +290,7 @@ class _VideoDetailPageState extends State<VideoDetailPage>
plPlayerController?.play();
}
plPlayerController?.addStatusLister(playerListener);
appbarStream.add(0);
super.didPopNext();
}
@ -490,21 +484,6 @@ class _VideoDetailPageState extends State<VideoDetailPage>
);
}
/// 稍后再看控制器初始化
// void watchLaterControllerInit() {
// _laterCtr = AnimationController(
// duration: const Duration(milliseconds: 300),
// vsync: this,
// );
// _laterOffsetAni = Tween<Offset>(
// begin: const Offset(0.0, 1.0),
// end: Offset.zero,
// ).animate(CurvedAnimation(
// parent: _laterCtr,
// curve: Curves.easeInOut,
// ));
// }
@override
Widget build(BuildContext context) {
final sizeContext = MediaQuery.sizeOf(context);