mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-06 09:13:48 +08:00
chore: clean up
opt: pages Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
@@ -2,6 +2,7 @@ import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:PiliPlus/build_config.dart';
|
||||
import 'package:PiliPlus/common/widgets/dialog.dart';
|
||||
import 'package:PiliPlus/services/loggeer.dart';
|
||||
import 'package:PiliPlus/utils/accounts/account.dart';
|
||||
import 'package:PiliPlus/utils/login_utils.dart';
|
||||
@@ -12,7 +13,6 @@ import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
|
||||
import 'package:package_info_plus/package_info_plus.dart';
|
||||
import 'package:PiliPlus/models/github/latest.dart';
|
||||
import 'package:PiliPlus/utils/storage.dart';
|
||||
import 'package:PiliPlus/utils/utils.dart';
|
||||
import '../../utils/cache_manage.dart';
|
||||
@@ -28,16 +28,33 @@ class AboutPage extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _AboutPageState extends State<AboutPage> {
|
||||
final AboutController _aboutController = Get.put(AboutController());
|
||||
final String _sourceCodeUrl = 'https://github.com/bggRGjQaUbCoE/PiliPlus';
|
||||
final String _originSourceCodeUrl = 'https://github.com/guozhigq/pilipala';
|
||||
final String _upstreamUrl = 'https://github.com/orz12/PiliPalaX';
|
||||
|
||||
RxString currentVersion = ''.obs;
|
||||
RxString cacheSize = ''.obs;
|
||||
|
||||
late int _pressCount = 0;
|
||||
|
||||
late Color outline;
|
||||
late TextStyle subTitleStyle;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
getCacheSize();
|
||||
getCurrentApp();
|
||||
}
|
||||
|
||||
Future getCacheSize() async {
|
||||
cacheSize.value = await CacheManage().loadApplicationCache();
|
||||
}
|
||||
|
||||
Future getCurrentApp() async {
|
||||
var currentInfo = await PackageInfo.fromPlatform();
|
||||
String buildNumber = currentInfo.buildNumber;
|
||||
currentVersion.value = "${currentInfo.version}+$buildNumber";
|
||||
}
|
||||
|
||||
@override
|
||||
void didChangeDependencies() {
|
||||
super.didChangeDependencies();
|
||||
@@ -46,18 +63,6 @@ class _AboutPageState extends State<AboutPage> {
|
||||
TextStyle(fontSize: 13, color: Theme.of(context).colorScheme.outline);
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
// 读取缓存占用
|
||||
getCacheSize();
|
||||
}
|
||||
|
||||
Future<void> getCacheSize() async {
|
||||
final res = await CacheManage().loadApplicationCache();
|
||||
_aboutController.cacheSize.value = res;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
@@ -123,12 +128,11 @@ class _AboutPageState extends State<AboutPage> {
|
||||
Obx(
|
||||
() => ListTile(
|
||||
onTap: () => Utils.checkUpdate(false),
|
||||
onLongPress: () =>
|
||||
Utils.copyText(_aboutController.currentVersion.value),
|
||||
onLongPress: () => Utils.copyText(currentVersion.value),
|
||||
title: const Text('当前版本'),
|
||||
leading: const Icon(Icons.commit_outlined),
|
||||
trailing: Text(
|
||||
_aboutController.currentVersion.value,
|
||||
currentVersion.value,
|
||||
style: subTitleStyle,
|
||||
),
|
||||
),
|
||||
@@ -156,24 +160,6 @@ Commit Hash: ${BuildConfig.commitHash}''',
|
||||
title: const Text('Source Code'),
|
||||
subtitle: Text(_sourceCodeUrl, style: subTitleStyle),
|
||||
),
|
||||
ListTile(
|
||||
onTap: () => PageUtils.launchURL(_originSourceCodeUrl),
|
||||
leading: const Icon(Icons.code),
|
||||
title: const Text('Origin'),
|
||||
subtitle: Text(
|
||||
_originSourceCodeUrl,
|
||||
style: subTitleStyle,
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
onTap: () => PageUtils.launchURL(_upstreamUrl),
|
||||
leading: const Icon(Icons.code),
|
||||
title: const Text('Upstream'),
|
||||
subtitle: Text(
|
||||
_upstreamUrl,
|
||||
style: subTitleStyle,
|
||||
),
|
||||
),
|
||||
if (Platform.isAndroid)
|
||||
ListTile(
|
||||
onTap: () {
|
||||
@@ -189,22 +175,7 @@ Commit Hash: ${BuildConfig.commitHash}''',
|
||||
),
|
||||
ListTile(
|
||||
onTap: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return SimpleDialog(
|
||||
clipBehavior: Clip.hardEdge,
|
||||
title: const Text('问题反馈'),
|
||||
children: [
|
||||
ListTile(
|
||||
title: const Text('GitHub Issue'),
|
||||
onTap: () =>
|
||||
PageUtils.launchURL('$_sourceCodeUrl/issues'),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
PageUtils.launchURL('$_sourceCodeUrl/issues');
|
||||
},
|
||||
leading: const Icon(Icons.feedback_outlined),
|
||||
title: const Text('问题反馈'),
|
||||
@@ -225,15 +196,30 @@ Commit Hash: ${BuildConfig.commitHash}''',
|
||||
trailing: Icon(Icons.arrow_forward, size: 16, color: outline),
|
||||
),
|
||||
ListTile(
|
||||
onTap: () async {
|
||||
await CacheManage().clearCacheAll(context);
|
||||
getCacheSize();
|
||||
onTap: () {
|
||||
showConfirmDialog(
|
||||
context: context,
|
||||
title: '提示',
|
||||
content: '该操作将清除图片及网络请求缓存数据,确认清除?',
|
||||
onConfirm: () async {
|
||||
SmartDialog.showLoading(msg: '正在清除...');
|
||||
try {
|
||||
await CacheManage.clearLibraryCache();
|
||||
SmartDialog.showToast('清除成功');
|
||||
} catch (err) {
|
||||
SmartDialog.showToast(err.toString());
|
||||
} finally {
|
||||
SmartDialog.dismiss();
|
||||
}
|
||||
getCacheSize();
|
||||
},
|
||||
);
|
||||
},
|
||||
leading: const Icon(Icons.delete_outline),
|
||||
title: const Text('清除缓存'),
|
||||
subtitle: Obx(
|
||||
() => Text(
|
||||
'图片及网络缓存 ${_aboutController.cacheSize.value}',
|
||||
'图片及网络缓存 ${cacheSize.value}',
|
||||
style: subTitleStyle,
|
||||
),
|
||||
),
|
||||
@@ -254,14 +240,6 @@ Commit Hash: ${BuildConfig.commitHash}''',
|
||||
Get.back();
|
||||
String res = jsonEncode(Accounts.account.toMap());
|
||||
Utils.copyText(res);
|
||||
// if (context.mounted) {
|
||||
// showDialog(
|
||||
// context: context,
|
||||
// builder: (context) => AlertDialog(
|
||||
// content: SelectableText('$res'),
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
@@ -328,78 +306,79 @@ Commit Hash: ${BuildConfig.commitHash}''',
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
title: const Text('导入/导出设置'),
|
||||
dense: false,
|
||||
leading: const Icon(Icons.import_export_outlined),
|
||||
onTap: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return SimpleDialog(
|
||||
clipBehavior: Clip.hardEdge,
|
||||
title: const Text('导入/导出设置'),
|
||||
children: [
|
||||
ListTile(
|
||||
title: const Text('导出设置至剪贴板'),
|
||||
onTap: () async {
|
||||
Get.back();
|
||||
String data = await GStorage.exportAllSettings();
|
||||
Utils.copyText(data);
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
title: const Text('从剪贴板导入设置'),
|
||||
onTap: () async {
|
||||
Get.back();
|
||||
ClipboardData? data =
|
||||
await Clipboard.getData('text/plain');
|
||||
if (data == null ||
|
||||
data.text == null ||
|
||||
data.text!.isEmpty) {
|
||||
SmartDialog.showToast('剪贴板无数据');
|
||||
return;
|
||||
}
|
||||
if (!context.mounted) return;
|
||||
await showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return AlertDialog(
|
||||
title: const Text('是否导入如下设置?'),
|
||||
content: SingleChildScrollView(
|
||||
child: Text(data.text!),
|
||||
title: const Text('导入/导出设置'),
|
||||
dense: false,
|
||||
leading: const Icon(Icons.import_export_outlined),
|
||||
onTap: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return SimpleDialog(
|
||||
clipBehavior: Clip.hardEdge,
|
||||
title: const Text('导入/导出设置'),
|
||||
children: [
|
||||
ListTile(
|
||||
title: const Text('导出设置至剪贴板'),
|
||||
onTap: () async {
|
||||
Get.back();
|
||||
String data = await GStorage.exportAllSettings();
|
||||
Utils.copyText(data);
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
title: const Text('从剪贴板导入设置'),
|
||||
onTap: () async {
|
||||
Get.back();
|
||||
ClipboardData? data =
|
||||
await Clipboard.getData('text/plain');
|
||||
if (data == null ||
|
||||
data.text == null ||
|
||||
data.text!.isEmpty) {
|
||||
SmartDialog.showToast('剪贴板无数据');
|
||||
return;
|
||||
}
|
||||
if (!context.mounted) return;
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return AlertDialog(
|
||||
title: const Text('是否导入如下设置?'),
|
||||
content: SingleChildScrollView(
|
||||
child: Text(data.text!),
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: Get.back,
|
||||
child: Text(
|
||||
'取消',
|
||||
style: TextStyle(color: outline),
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: Get.back,
|
||||
child: Text(
|
||||
'取消',
|
||||
style: TextStyle(color: outline),
|
||||
),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () async {
|
||||
Get.back();
|
||||
try {
|
||||
await GStorage.importAllSettings(
|
||||
data.text!);
|
||||
SmartDialog.showToast('导入成功');
|
||||
} catch (e) {
|
||||
SmartDialog.showToast('导入失败:$e');
|
||||
}
|
||||
},
|
||||
child: const Text('确定'),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}),
|
||||
TextButton(
|
||||
onPressed: () async {
|
||||
Get.back();
|
||||
try {
|
||||
await GStorage.importAllSettings(
|
||||
data.text!);
|
||||
SmartDialog.showToast('导入成功');
|
||||
} catch (e) {
|
||||
SmartDialog.showToast('导入失败:$e');
|
||||
}
|
||||
},
|
||||
child: const Text('确定'),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
title: const Text('重置所有设置'),
|
||||
leading: const Icon(Icons.settings_backup_restore_outlined),
|
||||
@@ -449,32 +428,9 @@ Commit Hash: ${BuildConfig.commitHash}''',
|
||||
);
|
||||
},
|
||||
),
|
||||
SizedBox(height: MediaQuery.paddingOf(context).bottom + 80),
|
||||
const SizedBox(height: 80),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class AboutController extends GetxController {
|
||||
RxString currentVersion = ''.obs;
|
||||
RxString remoteVersion = ''.obs;
|
||||
LatestDataModel? remoteAppInfo;
|
||||
RxBool isUpdate = true.obs;
|
||||
RxBool isLoading = true.obs;
|
||||
LatestDataModel? data;
|
||||
RxString cacheSize = ''.obs;
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
getCurrentApp();
|
||||
}
|
||||
|
||||
// 获取当前版本
|
||||
Future getCurrentApp() async {
|
||||
var currentInfo = await PackageInfo.fromPlatform();
|
||||
String buildNumber = currentInfo.buildNumber;
|
||||
currentVersion.value = "${currentInfo.version}+$buildNumber";
|
||||
}
|
||||
}
|
||||
@@ -103,7 +103,6 @@ class BangumiIntroController
|
||||
var result = await UserHttp.videoTags(bvid: bvid);
|
||||
if (result['status']) {
|
||||
videoTags = result['data'];
|
||||
// debugPrint('tags: ${result['data']}');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -562,10 +561,6 @@ class BangumiIntroController
|
||||
scriptContent['props']['pageProps']['followState']['isFollowed'];
|
||||
followStatus.value =
|
||||
scriptContent['props']['pageProps']['followState']['followStatus'];
|
||||
// int progress = scriptContent['props']['pageProps']['dehydratedState']
|
||||
// ['queries'][0]['state']['data']['result']
|
||||
// ['play_view_business_info']['user_status']['watch_progress']
|
||||
// ['current_watch_progress'];
|
||||
}
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
@@ -394,16 +394,6 @@ class _BangumiInfoState extends State<BangumiInfo> {
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
// 点赞收藏转发 布局样式1
|
||||
// SingleChildScrollView(
|
||||
// padding: const EdgeInsets.only(top: 7, bottom: 7),
|
||||
// scrollDirection: Axis.horizontal,
|
||||
// child: actionRow(
|
||||
// context,
|
||||
// bangumiIntroController,
|
||||
// videoDetailCtr,
|
||||
// ),
|
||||
// ),
|
||||
// 点赞收藏转发 布局样式2
|
||||
actionGrid(context, bangumiIntroController),
|
||||
// 番剧分p
|
||||
|
||||
@@ -68,24 +68,8 @@ class _BangumiPanelState extends State<BangumiPanel> {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
// void changeFucCall(item, i) async {
|
||||
// if (item.badge != null && item.badge == '会员' && vipStatus != 1) {
|
||||
// SmartDialog.showToast('需要大会员');
|
||||
// return;
|
||||
// }
|
||||
// await widget.changeFuc!(
|
||||
// item.bvid,
|
||||
// item.cid,
|
||||
// item.aid,
|
||||
// );
|
||||
// currentIndex = i;
|
||||
// setState(() {});
|
||||
// scrollToIndex();
|
||||
// }
|
||||
|
||||
void scrollToIndex() {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
// 在回调函数中获取更新后的状态
|
||||
listViewScrollCtr.animateTo(
|
||||
(currentIndex * 150.0).clamp(listViewScrollCtr.position.minScrollExtent,
|
||||
listViewScrollCtr.position.maxScrollExtent),
|
||||
@@ -148,11 +132,12 @@ class _BangumiPanelState extends State<BangumiPanel> {
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemCount: widget.pages.length,
|
||||
itemExtent: 150,
|
||||
itemBuilder: (BuildContext context, int i) {
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
final item = widget.pages[index];
|
||||
return Container(
|
||||
width: 150,
|
||||
margin: EdgeInsets.only(
|
||||
right: i == widget.pages.length - 1 ? 0 : 10,
|
||||
right: index == widget.pages.length - 1 ? 0 : 10,
|
||||
),
|
||||
child: Material(
|
||||
color: Theme.of(context).colorScheme.onInverseSurface,
|
||||
@@ -160,24 +145,19 @@ class _BangumiPanelState extends State<BangumiPanel> {
|
||||
clipBehavior: Clip.hardEdge,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
if (widget.pages[i].badge != null &&
|
||||
widget.pages[i].badge == '会员' &&
|
||||
if (item.badge != null &&
|
||||
item.badge == '会员' &&
|
||||
vipStatus != 1) {
|
||||
SmartDialog.showToast('需要大会员');
|
||||
// return;
|
||||
}
|
||||
widget.changeFuc(
|
||||
widget.pages[i].epId,
|
||||
widget.pages[i].bvid,
|
||||
widget.pages[i].cid,
|
||||
widget.pages[i].aid,
|
||||
widget.pages[i].cover,
|
||||
item.epId,
|
||||
item.bvid,
|
||||
item.cid,
|
||||
item.aid,
|
||||
item.cover,
|
||||
);
|
||||
// currentIndex = i;
|
||||
// setState(() {});
|
||||
// scrollToIndex();
|
||||
},
|
||||
//changeFucCall(widget.pages[i], i),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 8, horizontal: 10),
|
||||
@@ -186,7 +166,7 @@ class _BangumiPanelState extends State<BangumiPanel> {
|
||||
children: <Widget>[
|
||||
Row(
|
||||
children: [
|
||||
if (i == currentIndex) ...<Widget>[
|
||||
if (index == currentIndex) ...<Widget>[
|
||||
Image.asset(
|
||||
'assets/images/live.png',
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
@@ -197,32 +177,32 @@ class _BangumiPanelState extends State<BangumiPanel> {
|
||||
],
|
||||
Expanded(
|
||||
child: Text(
|
||||
widget.pages[i].title ?? '第${i + 1}话',
|
||||
maxLines: (widget.pages[i].longTitle != null &&
|
||||
widget.pages[i].longTitle != '')
|
||||
item.title ?? '第${index + 1}话',
|
||||
maxLines: (item.longTitle != null &&
|
||||
item.longTitle != '')
|
||||
? 1
|
||||
: 2,
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: i == currentIndex
|
||||
color: index == currentIndex
|
||||
? Theme.of(context).colorScheme.primary
|
||||
: Theme.of(context)
|
||||
.colorScheme
|
||||
.onSurface),
|
||||
)),
|
||||
const SizedBox(width: 2),
|
||||
if (widget.pages[i].badge != null) ...[
|
||||
if (item.badge != null) ...[
|
||||
const Spacer(),
|
||||
if (widget.pages[i].badge == '会员') ...[
|
||||
if (item.badge == '会员') ...[
|
||||
Image.asset(
|
||||
'assets/images/big-vip.png',
|
||||
height: 16,
|
||||
semanticLabel: "大会员",
|
||||
),
|
||||
],
|
||||
if (widget.pages[i].badge != '会员') ...[
|
||||
if (item.badge != '会员') ...[
|
||||
Text(
|
||||
widget.pages[i].badge!,
|
||||
item.badge!,
|
||||
style: TextStyle(
|
||||
fontSize: 11,
|
||||
color:
|
||||
@@ -233,15 +213,15 @@ class _BangumiPanelState extends State<BangumiPanel> {
|
||||
]
|
||||
],
|
||||
),
|
||||
if (widget.pages[i].longTitle != null &&
|
||||
widget.pages[i].longTitle != '') ...[
|
||||
if (item.longTitle != null &&
|
||||
item.longTitle != '') ...[
|
||||
const SizedBox(height: 3),
|
||||
Text(
|
||||
widget.pages[i].longTitle!,
|
||||
item.longTitle!,
|
||||
maxLines: 1,
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: i == currentIndex
|
||||
color: index == currentIndex
|
||||
? Theme.of(context).colorScheme.primary
|
||||
: Theme.of(context)
|
||||
.colorScheme
|
||||
|
||||
@@ -70,7 +70,6 @@ class _DanmakuBlockPageState extends State<DanmakuBlockPage> {
|
||||
TextField(
|
||||
controller: textController,
|
||||
autofocus: true,
|
||||
//decoration: InputDecoration(hintText: hintText),
|
||||
)
|
||||
]),
|
||||
actions: <Widget>[
|
||||
|
||||
@@ -70,7 +70,6 @@ class DynamicsController extends GetxController
|
||||
Future queryFollowing2() async {
|
||||
if (upData.value.upList != null &&
|
||||
upData.value.upList!.length >= allFollowedUpsTotal) {
|
||||
// SmartDialog.showToast('没有更多了');
|
||||
return;
|
||||
}
|
||||
var res = await FollowHttp.followings(
|
||||
@@ -187,7 +186,6 @@ class DynamicsController extends GetxController
|
||||
await controller.onRefresh();
|
||||
}
|
||||
|
||||
// 返回顶部并刷新
|
||||
@override
|
||||
void animateToTop() async {
|
||||
controller.animateToTop();
|
||||
|
||||
@@ -31,7 +31,6 @@ import '../../../utils/grid.dart';
|
||||
import '../widgets/dynamic_panel.dart';
|
||||
|
||||
class DynamicDetailPage extends StatefulWidget {
|
||||
// const DynamicDetailPage({super.key});
|
||||
const DynamicDetailPage({super.key});
|
||||
|
||||
@override
|
||||
@@ -43,7 +42,6 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
|
||||
late DynamicDetailController _dynamicDetailController;
|
||||
AnimationController? _fabAnimationCtr;
|
||||
final RxBool _visibleTitle = false.obs;
|
||||
// String? action;
|
||||
// 回复类型
|
||||
late int replyType;
|
||||
bool _isFabVisible = true;
|
||||
@@ -124,8 +122,6 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
|
||||
Map args = Get.arguments;
|
||||
// 楼层
|
||||
int floor = args['floor'];
|
||||
// 从action栏点击进入
|
||||
// action = args.containsKey('action') ? args['action'] : null;
|
||||
// 评论类型
|
||||
int commentType = args['item'].basic!['comment_type'] ?? 11;
|
||||
replyType = (commentType == 0) ? 11 : commentType;
|
||||
|
||||
@@ -144,10 +144,7 @@ class _DynamicsTabPageState
|
||||
sliver: dynamicsWaterfallFlow
|
||||
? SliverWaterfallFlow.extent(
|
||||
maxCrossAxisExtent: Grid.smallCardWidth * 2,
|
||||
//cacheExtent: 0.0,
|
||||
crossAxisSpacing: StyleString.cardSpace / 2,
|
||||
// mainAxisSpacing: StyleString.cardSpace / 2,
|
||||
|
||||
lastChildLayoutTypeBuilder: (index) {
|
||||
if (index == loadingState.response!.length - 1) {
|
||||
controller.onLoadMore();
|
||||
@@ -163,7 +160,6 @@ class _DynamicsTabPageState
|
||||
DynamicPanel(
|
||||
item: i,
|
||||
onRemove: controller.onRemove,
|
||||
// onSetTop: controller.onSetTop,
|
||||
),
|
||||
] else ...[
|
||||
for (var i in loadingState.response!)
|
||||
@@ -172,7 +168,6 @@ class _DynamicsTabPageState
|
||||
DynamicPanel(
|
||||
item: i,
|
||||
onRemove: controller.onRemove,
|
||||
// onSetTop: controller.onSetTop,
|
||||
),
|
||||
]
|
||||
],
|
||||
@@ -198,7 +193,6 @@ class _DynamicsTabPageState
|
||||
return DynamicPanel(
|
||||
item: item,
|
||||
onRemove: controller.onRemove,
|
||||
// onSetTop: controller.onSetTop,
|
||||
);
|
||||
}
|
||||
return const SizedBox.shrink();
|
||||
|
||||
@@ -131,7 +131,6 @@ Widget addWidget(item, context, type, {floor = 1}) {
|
||||
)
|
||||
],
|
||||
),
|
||||
// TextButton(onPressed: () {}, child: Text('123'))
|
||||
),
|
||||
),
|
||||
)
|
||||
@@ -140,60 +139,6 @@ Widget addWidget(item, context, type, {floor = 1}) {
|
||||
case 'ADDITIONAL_TYPE_GOODS':
|
||||
// 商品
|
||||
return const SizedBox();
|
||||
// return Padding(
|
||||
// padding: const EdgeInsets.only(top: 6),
|
||||
// child: InkWell(
|
||||
// onTap: () {},
|
||||
// child: Container(
|
||||
// padding:
|
||||
// const EdgeInsets.only(left: 12, top: 8, right: 12, bottom: 8),
|
||||
// decoration: BoxDecoration(
|
||||
// color: bgColor,
|
||||
// borderRadius: const BorderRadius.all(Radius.circular(6)),
|
||||
// ),
|
||||
// child: Row(
|
||||
// children: [
|
||||
// NetworkImgLayer(
|
||||
// width: 75,
|
||||
// height: 75,
|
||||
// src: dynamicProperty[type].items.first.cover,
|
||||
// ),
|
||||
// const SizedBox(width: 10),
|
||||
// Expanded(
|
||||
// child: Column(
|
||||
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||
// mainAxisAlignment: MainAxisAlignment.start,
|
||||
// children: [
|
||||
// Text(
|
||||
// dynamicProperty[type].items.first.name,
|
||||
// maxLines: 1,
|
||||
// overflow: TextOverflow.ellipsis,
|
||||
// ),
|
||||
// Text(
|
||||
// dynamicProperty[type].items.first.brief,
|
||||
// maxLines: 1,
|
||||
// style: TextStyle(
|
||||
// color: Theme.of(context).colorScheme.outline,
|
||||
// fontSize: Theme.of(context)
|
||||
// .textTheme
|
||||
// .labelMedium!
|
||||
// .fontSize,
|
||||
// ),
|
||||
// ),
|
||||
// const SizedBox(height: 2),
|
||||
// Text(
|
||||
// dynamicProperty[type].items.first.price,
|
||||
// style: TextStyle(
|
||||
// color: Theme.of(context).colorScheme.primary,
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// ),);
|
||||
case 'ADDITIONAL_TYPE_MATCH':
|
||||
return const SizedBox();
|
||||
case 'ADDITIONAL_TYPE_COMMON':
|
||||
|
||||
@@ -94,7 +94,6 @@ class AuthorPanel extends StatelessWidget {
|
||||
children: [
|
||||
Text(
|
||||
item.modules.moduleAuthor.name,
|
||||
// semanticsLabel: "UP主:${item.modules.moduleAuthor.name}",
|
||||
style: TextStyle(
|
||||
color: item.modules.moduleAuthor!.vip != null &&
|
||||
item.modules.moduleAuthor!.vip['status'] > 0 &&
|
||||
@@ -157,20 +156,6 @@ class AuthorPanel extends StatelessWidget {
|
||||
? Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
// GestureDetector(
|
||||
// onTap:
|
||||
// item.modules.moduleAuthor.decorate['jump_url'] != null
|
||||
// ? () {
|
||||
// Get.toNamed(
|
||||
// '/webview',
|
||||
// parameters: {
|
||||
// 'url':
|
||||
// '${item.modules.moduleAuthor.decorate['jump_url']}'
|
||||
// },
|
||||
// );
|
||||
// }
|
||||
// : null,
|
||||
// child:
|
||||
Stack(
|
||||
clipBehavior: Clip.none,
|
||||
alignment: Alignment.centerRight,
|
||||
@@ -210,7 +195,6 @@ class AuthorPanel extends StatelessWidget {
|
||||
),
|
||||
],
|
||||
),
|
||||
// ),
|
||||
_moreWidget(context),
|
||||
],
|
||||
)
|
||||
@@ -294,7 +278,6 @@ class AuthorPanel extends StatelessWidget {
|
||||
}
|
||||
},
|
||||
minLeadingWidth: 0,
|
||||
// dense: true,
|
||||
leading: const Icon(Icons.watch_later_outlined, size: 19),
|
||||
title: Text(
|
||||
'稍后再看',
|
||||
|
||||
@@ -66,7 +66,6 @@ Widget content(bool isSave, BuildContext context, item, source, callback) {
|
||||
item.modules.moduleDynamic.major.opus.pics.isNotEmpty)
|
||||
Text.rich(
|
||||
picsNodes(),
|
||||
// semanticsLabel: '动态图片',
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@@ -30,9 +30,6 @@ class DynamicPanel extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
// padding: source == 'detail'
|
||||
// ? const EdgeInsets.only(bottom: 12)
|
||||
// : EdgeInsets.zero,
|
||||
decoration: isSave ||
|
||||
(source == 'detail' &&
|
||||
Get.context!.orientation == Orientation.landscape)
|
||||
@@ -47,11 +44,7 @@ class DynamicPanel extends StatelessWidget {
|
||||
),
|
||||
child: Material(
|
||||
elevation: 0,
|
||||
// clipBehavior: Clip.hardEdge,
|
||||
color: Colors.transparent,
|
||||
// shape: RoundedRectangleBorder(
|
||||
// borderRadius: BorderRadius.circular(5),
|
||||
// ),
|
||||
child: InkWell(
|
||||
onTap: source == 'detail' &&
|
||||
[
|
||||
|
||||
@@ -106,22 +106,6 @@ Widget forWard(bool isSave, item, BuildContext context, source, callback,
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
|
||||
/// fix #话题跟content重复
|
||||
// if (item.modules.moduleDynamic.topic != null) ...[
|
||||
// Padding(
|
||||
// padding: floor == 2
|
||||
// ? EdgeInsets.zero
|
||||
// : const EdgeInsets.only(left: 12, right: 12),
|
||||
// child: GestureDetector(
|
||||
// child: Text(
|
||||
// '#${item.modules.moduleDynamic.topic.name}',
|
||||
// style: authorStyle,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
|
||||
if (richNodes != null)
|
||||
Text.rich(
|
||||
richNodes,
|
||||
@@ -140,10 +124,7 @@ Widget forWard(bool isSave, item, BuildContext context, source, callback,
|
||||
if (hasPics) ...[
|
||||
Text.rich(
|
||||
picsNodes(item.modules.moduleDynamic.major.opus.pics, callback),
|
||||
// semanticsLabel: '动态图片',
|
||||
),
|
||||
// if (item.modules.moduleDynamic.additional != null)
|
||||
// const SizedBox(height: 4),
|
||||
],
|
||||
const SizedBox(height: 4),
|
||||
],
|
||||
@@ -206,11 +187,6 @@ Widget forWard(bool isSave, item, BuildContext context, source, callback,
|
||||
: const SizedBox.shrink(),
|
||||
_ => const SizedBox.shrink(),
|
||||
};
|
||||
// return Container(
|
||||
// padding:
|
||||
// const EdgeInsets.only(left: 10, top: 12, right: 10, bottom: 10),
|
||||
// color: Theme.of(context).dividerColor.withOpacity(0.08),
|
||||
// child: articlePanel(item, context, floor: floor));
|
||||
// 转发
|
||||
case 'DYNAMIC_TYPE_FORWARD':
|
||||
return InkWell(
|
||||
|
||||
@@ -40,9 +40,6 @@ InlineSpan? richNode(item, BuildContext context) {
|
||||
return null;
|
||||
} else {
|
||||
for (var i in richTextNodes) {
|
||||
/// fix 渲染专栏时内容会重复
|
||||
// if (item.modules.moduleDynamic.major.opus.title == null &&
|
||||
// i.type == 'RICH_TEXT_NODE_TYPE_TEXT') {
|
||||
if (i.type == 'RICH_TEXT_NODE_TYPE_TEXT') {
|
||||
spanChildren.add(
|
||||
TextSpan(text: i.origText, style: const TextStyle(height: 1.65)));
|
||||
@@ -289,121 +286,7 @@ InlineSpan? richNode(item, BuildContext context) {
|
||||
}
|
||||
}
|
||||
|
||||
// if (contentType == 'major' &&
|
||||
// item.modules.moduleDynamic.major.opus.pics.isNotEmpty) {
|
||||
// // 图片可能跟其他widget重复渲染
|
||||
// List<OpusPicsModel> pics = item.modules.moduleDynamic.major.opus.pics;
|
||||
// int len = pics.length;
|
||||
// List<String> picList = [];
|
||||
|
||||
// if (len == 1) {
|
||||
// OpusPicsModel pictureItem = pics.first;
|
||||
// picList.add(pictureItem.url!);
|
||||
// spanChildren.add(const TextSpan(text: '\n'));
|
||||
// spanChildren.add(
|
||||
// WidgetSpan(
|
||||
// child: LayoutBuilder(
|
||||
// builder: (context, BoxConstraints box) {
|
||||
// return GestureDetector(
|
||||
// onTap: () {
|
||||
// showDialog(
|
||||
// useSafeArea: false,
|
||||
// context: context,
|
||||
// builder: (context) {
|
||||
// return ImagePreview(initialPage: 0, imgList: picList);
|
||||
// },
|
||||
// );
|
||||
// },
|
||||
// child: Padding(
|
||||
// padding: const EdgeInsets.only(top: 4),
|
||||
// child: NetworkImgLayer(
|
||||
// src: pictureItem.url,
|
||||
// width: box.maxWidth / 2,
|
||||
// height: box.maxWidth *
|
||||
// 0.5 *
|
||||
// (pictureItem.height != null &&
|
||||
// pictureItem.width != null
|
||||
// ? pictureItem.height! / pictureItem.width!
|
||||
// : 1),
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
// },
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
// if (len > 1) {
|
||||
// List<Widget> list = [];
|
||||
// for (var i = 0; i < len; i++) {
|
||||
// picList.add(pics[i].url!);
|
||||
// list.add(
|
||||
// LayoutBuilder(
|
||||
// builder: (context, BoxConstraints box) {
|
||||
// return GestureDetector(
|
||||
// onTap: () {
|
||||
// showDialog(
|
||||
// useSafeArea: false,
|
||||
// context: context,
|
||||
// builder: (context) {
|
||||
// return ImagePreview(initialPage: i, imgList: picList);
|
||||
// },
|
||||
// );
|
||||
// },
|
||||
// child: NetworkImgLayer(
|
||||
// src: pics[i].url,
|
||||
// width: box.maxWidth,
|
||||
// height: box.maxWidth,
|
||||
// ),
|
||||
// );
|
||||
// },
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
// spanChildren.add(
|
||||
// WidgetSpan(
|
||||
// child: LayoutBuilder(
|
||||
// builder: (context, BoxConstraints box) {
|
||||
// double maxWidth = box.maxWidth;
|
||||
// double crossCount = len < 3 ? 2 : 3;
|
||||
// double height = maxWidth /
|
||||
// crossCount *
|
||||
// (len % crossCount == 0
|
||||
// ? len ~/ crossCount
|
||||
// : len ~/ crossCount + 1) +
|
||||
// 6;
|
||||
// return Container(
|
||||
// padding: const EdgeInsets.only(top: 6),
|
||||
// height: height,
|
||||
// child: GridView.count(
|
||||
// padding: EdgeInsets.zero,
|
||||
// physics: const NeverScrollableScrollPhysics(),
|
||||
// crossAxisCount: crossCount.toInt(),
|
||||
// mainAxisSpacing: 4.0,
|
||||
// crossAxisSpacing: 4.0,
|
||||
// childAspectRatio: 1,
|
||||
// children: list,
|
||||
// ),
|
||||
// );
|
||||
// },
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
// spanChildren.add(
|
||||
// WidgetSpan(
|
||||
// child: NetworkImgLayer(
|
||||
// src: pics.first.url,
|
||||
// type: 'emote',
|
||||
// width: 100,
|
||||
// height: 200,
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
return TextSpan(
|
||||
children: spanChildren,
|
||||
);
|
||||
return TextSpan(children: spanChildren);
|
||||
}
|
||||
} catch (err) {
|
||||
debugPrint('❌rich_node_panel err: $err');
|
||||
|
||||
@@ -109,36 +109,14 @@ class _UpPanelState extends State<UpPanel> {
|
||||
feedBack();
|
||||
if (data.type == 'up') {
|
||||
widget.dynamicsController.currentMid = data.mid;
|
||||
// dynamicsController.mid.value = data.mid;
|
||||
widget.dynamicsController
|
||||
..upInfo.value = data
|
||||
..onSelectUp(data.mid);
|
||||
// int liveLen = liveList.length;
|
||||
// int upLen = upList.length;
|
||||
// double itemWidth = contentWidth + itemPadding.horizontal;
|
||||
// double screenWidth = MediaQuery.sizeOf(context).width;
|
||||
// double moveDistance = 0.0;
|
||||
// if (itemWidth * (upList.length + liveList.length) <= screenWidth) {
|
||||
// } else if ((upLen - i - 0.5) * itemWidth > screenWidth / 2) {
|
||||
// moveDistance =
|
||||
// (i + liveLen + 0.5) * itemWidth + 46 - screenWidth / 2;
|
||||
// } else {
|
||||
// moveDistance = (upLen + liveLen) * itemWidth + 46 - screenWidth;
|
||||
// }
|
||||
|
||||
data.hasUpdate = false;
|
||||
// scrollController.animateTo(
|
||||
// moveDistance,
|
||||
// duration: const Duration(milliseconds: 500),
|
||||
// curve: Curves.easeInOut,
|
||||
// );
|
||||
|
||||
setState(() {});
|
||||
} else if (data.type == 'live') {
|
||||
// LiveItemModel liveItem = LiveItemModel.fromJson({
|
||||
// 'title': data.title,
|
||||
// 'uname': data.uname,
|
||||
// 'face': data.face,
|
||||
// 'roomid': data.roomId,
|
||||
// });
|
||||
Get.toNamed('/liveRoom?roomid=${data.roomId}');
|
||||
}
|
||||
},
|
||||
@@ -224,29 +202,6 @@ class _UpPanelState extends State<UpPanel> {
|
||||
}
|
||||
}
|
||||
|
||||
// class _SliverHeaderDelegate extends SliverPersistentHeaderDelegate {
|
||||
// _SliverHeaderDelegate({required this.height, required this.child});
|
||||
|
||||
// final double height;
|
||||
// final Widget child;
|
||||
|
||||
// @override
|
||||
// Widget build(
|
||||
// BuildContext context, double shrinkOffset, bool overlapsContent) {
|
||||
// return child;
|
||||
// }
|
||||
|
||||
// @override
|
||||
// double get maxExtent => height;
|
||||
|
||||
// @override
|
||||
// double get minExtent => height;
|
||||
|
||||
// @override
|
||||
// bool shouldRebuild(covariant SliverPersistentHeaderDelegate oldDelegate) =>
|
||||
// true;
|
||||
// }
|
||||
|
||||
class UpPanelSkeleton extends StatelessWidget {
|
||||
const UpPanelSkeleton({super.key});
|
||||
|
||||
|
||||
@@ -55,16 +55,12 @@ Widget videoSeasonWidget(source, item, context, type, {floor = 1}) {
|
||||
double width = box.maxWidth;
|
||||
return Stack(
|
||||
children: [
|
||||
// Hero(
|
||||
// tag: content.bvid,
|
||||
// child:
|
||||
NetworkImgLayer(
|
||||
width: width,
|
||||
height: width / StyleString.aspectRatio,
|
||||
src: content.cover,
|
||||
semanticsLabel: content.title,
|
||||
),
|
||||
// ),
|
||||
if (content?.badge?['text'] != null)
|
||||
PBadge(
|
||||
text: content.badge['text'],
|
||||
@@ -161,22 +157,6 @@ Widget videoSeasonWidget(source, item, context, type, {floor = 1}) {
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
],
|
||||
// const SizedBox(height: 4),
|
||||
/// fix #话题跟content重复
|
||||
// if (item.modules.moduleDynamic.topic != null) ...[
|
||||
// Padding(
|
||||
// padding: floor == 2
|
||||
// ? EdgeInsets.zero
|
||||
// : const EdgeInsets.only(left: 12, right: 12),
|
||||
// child: GestureDetector(
|
||||
// child: Text(
|
||||
// '#${item.modules.moduleDynamic.topic.name}',
|
||||
// style: authorStyle,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// const SizedBox(height: 6),
|
||||
// ],
|
||||
if (floor == 2 && item.modules.moduleDynamic.desc != null) ...[
|
||||
if (richNodes != null) Text.rich(richNodes),
|
||||
const SizedBox(height: 6),
|
||||
|
||||
@@ -121,15 +121,18 @@ class _FavFolderSortPageState extends State<FavFolderSortPage> {
|
||||
(index) {
|
||||
final item = sortList[index];
|
||||
final key = item.id.toString();
|
||||
return FavItem(
|
||||
return SizedBox(
|
||||
key: Key(key),
|
||||
heroTag: key,
|
||||
favFolderItem: item,
|
||||
onLongPress: index == 0
|
||||
? () {
|
||||
SmartDialog.showToast('默认收藏夹不支持排序');
|
||||
}
|
||||
: null,
|
||||
height: 98,
|
||||
child: FavItem(
|
||||
heroTag: key,
|
||||
favFolderItem: item,
|
||||
onLongPress: index == 0
|
||||
? () {
|
||||
SmartDialog.showToast('默认收藏夹不支持排序');
|
||||
}
|
||||
: null,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
|
||||
@@ -24,7 +24,6 @@ class FavDetailController
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
// item = Get.arguments;
|
||||
if (Get.parameters.keys.isNotEmpty) {
|
||||
mediaId = int.parse(Get.parameters['mediaId']!);
|
||||
heroTag = Get.parameters['heroTag']!;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import 'package:PiliPlus/build_config.dart';
|
||||
import 'package:PiliPlus/http/loading_state.dart';
|
||||
import 'package:PiliPlus/http/user.dart';
|
||||
import 'package:PiliPlus/models/user/fav_detail.dart';
|
||||
@@ -126,20 +125,13 @@ class _FavSortPageState extends State<FavSortPage> {
|
||||
),
|
||||
children: sortList
|
||||
.map(
|
||||
(item) => Stack(
|
||||
(item) => SizedBox(
|
||||
key: Key(item.id.toString()),
|
||||
children: [
|
||||
FavVideoCardH(
|
||||
isSort: true,
|
||||
videoItem: item,
|
||||
),
|
||||
if (BuildConfig.isDebug)
|
||||
Positioned(
|
||||
top: 35,
|
||||
right: 10,
|
||||
child: Text(item.id.toString()),
|
||||
)
|
||||
],
|
||||
height: 98,
|
||||
child: FavVideoCardH(
|
||||
isSort: true,
|
||||
videoItem: item,
|
||||
),
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
|
||||
@@ -6,6 +6,7 @@ import 'widgets/follow_list.dart';
|
||||
import 'widgets/owner_follow_list.dart';
|
||||
import 'package:PiliPlus/common/widgets/scroll_physics.dart';
|
||||
|
||||
// TODO: refactor
|
||||
class FollowPage extends StatefulWidget {
|
||||
const FollowPage({super.key});
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import 'package:PiliPlus/pages/follow/index.dart';
|
||||
|
||||
import 'follow_item.dart';
|
||||
|
||||
// TODO: refactor
|
||||
class FollowList extends StatefulWidget {
|
||||
final FollowController ctr;
|
||||
const FollowList({
|
||||
|
||||
@@ -9,6 +9,7 @@ import 'package:PiliPlus/models/member/tags.dart';
|
||||
import 'package:PiliPlus/pages/follow/index.dart';
|
||||
import 'follow_item.dart';
|
||||
|
||||
// TODO: refactor
|
||||
class OwnerFollowList extends StatefulWidget {
|
||||
final FollowController ctr;
|
||||
final MemberTagItemModel? tagItem;
|
||||
|
||||
@@ -30,6 +30,7 @@ class _HomePageState extends State<HomePage>
|
||||
Widget build(BuildContext context) {
|
||||
super.build(context);
|
||||
return Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
appBar: AppBar(toolbarHeight: 0),
|
||||
body: Column(
|
||||
children: [
|
||||
|
||||
@@ -7,8 +7,6 @@ import 'package:get/get.dart';
|
||||
|
||||
class HotController
|
||||
extends CommonListController<List<HotVideoItemModel>, HotVideoItemModel> {
|
||||
// int idx = 0;
|
||||
|
||||
late RxBool showHotRcmd = GStorage.showHotRcmd.obs;
|
||||
|
||||
@override
|
||||
@@ -17,24 +15,10 @@ class HotController
|
||||
queryData();
|
||||
}
|
||||
|
||||
// @override
|
||||
// Future onRefresh() {
|
||||
// idx = 0;
|
||||
// return super.onRefresh();
|
||||
// }
|
||||
|
||||
@override
|
||||
Future<LoadingState<List<HotVideoItemModel>>> customGetData() =>
|
||||
VideoHttp.hotVideoList(
|
||||
pn: currentPage,
|
||||
ps: 20,
|
||||
);
|
||||
|
||||
// @override
|
||||
// void handleSuccess(List currentList, List dataList) {
|
||||
// idx = (dataList.last as Card?)?.smallCoverV5.base.idx.toInt() ?? 0;
|
||||
// }
|
||||
|
||||
// @override
|
||||
// Future<LoadingState> customGetData() => VideoHttp.hotVideoListGrpc(idx: idx);
|
||||
}
|
||||
|
||||
@@ -127,16 +127,6 @@ class _HtmlRenderPageState extends State<HtmlRenderPage>
|
||||
}
|
||||
|
||||
void listener() {
|
||||
// 标题
|
||||
// if (scrollController.offset > 55 && !_visibleTitle) {
|
||||
// _visibleTitle = true;
|
||||
// titleStreamC.add(true);
|
||||
// } else if (scrollController.offset <= 55 && _visibleTitle) {
|
||||
// _visibleTitle = false;
|
||||
// titleStreamC.add(false);
|
||||
// }
|
||||
|
||||
// fab按钮
|
||||
final ScrollDirection direction1 =
|
||||
_htmlRenderCtr.scrollController.positions.first.userScrollDirection;
|
||||
late final ScrollDirection direction2 =
|
||||
|
||||
@@ -230,13 +230,6 @@ class _ReplyPageState extends CommonPublishPageState<LiveSendDmPanel> {
|
||||
Get.back();
|
||||
liveRoomController.savedDanmaku = null;
|
||||
SmartDialog.showToast('发送成功');
|
||||
// liveRoomController.plPlayerController.danmakuController?.addDanmaku(
|
||||
// DanmakuContentItem(
|
||||
// emoticonUnique ?? message,
|
||||
// type: DanmakuItemType.scroll,
|
||||
// selfSend: true,
|
||||
// ),
|
||||
// );
|
||||
} else {
|
||||
SmartDialog.showToast(res['msg']);
|
||||
}
|
||||
|
||||
@@ -126,7 +126,6 @@ class _LiveRoomPageState extends State<LiveRoomPage>
|
||||
ScreenBrightness().resetApplicationScreenBrightness();
|
||||
PlPlayerController.setPlayCallBack(null);
|
||||
_liveRoomController.msgStream?.close();
|
||||
// floating?.dispose();
|
||||
plPlayerController.removeStatusLister(playerListener);
|
||||
plPlayerController.dispose();
|
||||
super.dispose();
|
||||
@@ -423,17 +422,14 @@ class _LiveRoomPageState extends State<LiveRoomPage>
|
||||
),
|
||||
),
|
||||
),
|
||||
//刷新
|
||||
IconButton(
|
||||
tooltip: '刷新',
|
||||
onPressed: () {
|
||||
_futureBuilderFuture =
|
||||
_liveRoomController.queryLiveInfo();
|
||||
// videoSourceInit();
|
||||
},
|
||||
icon: const Icon(Icons.refresh),
|
||||
),
|
||||
//内置浏览器打开
|
||||
IconButton(
|
||||
tooltip: '浏览器打开',
|
||||
onPressed: () {
|
||||
|
||||
@@ -46,38 +46,7 @@ class BottomControl extends StatelessWidget implements PreferredSizeWidget {
|
||||
),
|
||||
onTap: onRefresh,
|
||||
),
|
||||
// // ComBtn(
|
||||
// icon: const Icon(
|
||||
// Icons.subtitles_outlined,
|
||||
// size: 18,
|
||||
// color: Colors.white,
|
||||
// ),
|
||||
// fuc: () => Get.back(),
|
||||
// ),
|
||||
const Spacer(),
|
||||
// ComBtn(
|
||||
// icon: const Icon(
|
||||
// Icons.hd_outlined,
|
||||
// size: 18,
|
||||
// color: Colors.white,
|
||||
// ),
|
||||
// fuc: () => {},
|
||||
// ),
|
||||
// const SizedBox(width: 4),
|
||||
// Obx(
|
||||
// () => ComBtn(
|
||||
// icon: Icon(
|
||||
// widget.liveRoomCtr!.volumeOff.value
|
||||
// ? Icons.volume_off_outlined
|
||||
// : Icons.volume_up_outlined,
|
||||
// size: 18,
|
||||
// color: Colors.white,
|
||||
// ),
|
||||
// fuc: () => {},
|
||||
// ),
|
||||
// ),
|
||||
// const SizedBox(width: 4),
|
||||
|
||||
Obx(
|
||||
() => IconButton(
|
||||
onPressed: () {
|
||||
@@ -175,21 +144,3 @@ class BottomControl extends StatelessWidget implements PreferredSizeWidget {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// class MSliderTrackShape extends RoundedRectSliderTrackShape {
|
||||
// @override
|
||||
// Rect getPreferredRect({
|
||||
// required RenderBox parentBox,
|
||||
// Offset offset = Offset.zero,
|
||||
// SliderThemeData? sliderTheme,
|
||||
// bool isEnabled = false,
|
||||
// bool isDiscrete = false,
|
||||
// }) {
|
||||
// const double trackHeight = 3;
|
||||
// final double trackLeft = offset.dx;
|
||||
// final double trackTop =
|
||||
// offset.dy + (parentBox.size.height - trackHeight) / 2 + 4;
|
||||
// final double trackWidth = parentBox.size.width;
|
||||
// return Rect.fromLTWH(trackLeft, trackTop, trackWidth, trackHeight);
|
||||
// }
|
||||
// }
|
||||
|
||||
@@ -65,7 +65,6 @@ class LiveRoomChat extends StatelessWidget {
|
||||
);
|
||||
} catch (err) {
|
||||
debugPrint(err.toString());
|
||||
// SmartDialog.showToast(err.toString());
|
||||
}
|
||||
},
|
||||
),
|
||||
|
||||
@@ -628,11 +628,9 @@ class LoginPageController extends GetxController
|
||||
break;
|
||||
default:
|
||||
SmartDialog.showToast(res['msg']);
|
||||
// login failed
|
||||
break;
|
||||
}
|
||||
}
|
||||
// });
|
||||
}
|
||||
|
||||
bool isGeeArgumentValid(String? geeGt, String? geeChallenge) {
|
||||
@@ -644,11 +642,7 @@ class LoginPageController extends GetxController
|
||||
Future<void> setAccount(Map tokenInfo, List cookieInfo) async {
|
||||
final account = LoginAccount(BiliCookieJar.fromList(cookieInfo),
|
||||
tokenInfo['access_token'], tokenInfo['refresh_token']);
|
||||
await Future.wait([
|
||||
account.onChange(),
|
||||
AnonymousAccount().delete()
|
||||
// .then((_) => Request.buvidActive(AnonymousAccount()))
|
||||
]);
|
||||
await Future.wait([account.onChange(), AnonymousAccount().delete()]);
|
||||
Accounts.accountMode.updateAll((_, a) => a == account ? account : a);
|
||||
if (Accounts.main.isLogin) {
|
||||
SmartDialog.showToast('登录成功');
|
||||
|
||||
@@ -22,7 +22,6 @@ class LoginPage extends StatefulWidget {
|
||||
|
||||
class _LoginPageState extends State<LoginPage> {
|
||||
final LoginPageController _loginPageCtr = Get.put(LoginPageController());
|
||||
// late Future<Map<String, dynamic>> codeFuture;
|
||||
// 二维码生成时间
|
||||
bool showPassword = false;
|
||||
GlobalKey globalKey = GlobalKey();
|
||||
@@ -41,7 +40,6 @@ class _LoginPageState extends State<LoginPage> {
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
// const SizedBox(width: 20),
|
||||
TextButton.icon(
|
||||
onPressed: _loginPageCtr.refreshQRCode,
|
||||
icon: const Icon(Icons.refresh),
|
||||
@@ -64,7 +62,6 @@ class _LoginPageState extends State<LoginPage> {
|
||||
Uint8List.fromList(pngBytes),
|
||||
fileName: picName,
|
||||
extension: 'png',
|
||||
// 保存到 PiliPlus文件夹
|
||||
androidRelativePath: "Pictures/PiliPlus",
|
||||
skipIfExists: false,
|
||||
);
|
||||
@@ -108,20 +105,6 @@ class _LoginPageState extends State<LoginPage> {
|
||||
),
|
||||
),
|
||||
);
|
||||
// return QrImageView(
|
||||
// backgroundColor: Colors.white,
|
||||
// eyeStyle: QrEyeStyle(
|
||||
// eyeShape: QrEyeShape.square,
|
||||
// color: Colors.black87,
|
||||
// ),
|
||||
// dataModuleStyle: QrDataModuleStyle(
|
||||
// dataModuleShape: QrDataModuleShape.square,
|
||||
// color: Colors.black87,
|
||||
// ),
|
||||
// data: _loginPageCtr.codeInfo.value['data']!['url']!,
|
||||
// size: 200,
|
||||
// semanticsLabel: '二维码',
|
||||
// );
|
||||
}),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
@@ -132,10 +115,6 @@ class _LoginPageState extends State<LoginPage> {
|
||||
)),
|
||||
Obx(() => GestureDetector(
|
||||
onTap: () {
|
||||
//以外部方式打开此链接
|
||||
// launchUrlString(
|
||||
// _loginPageCtr.codeInfo.value['data']?['url'] ?? "",
|
||||
// mode: LaunchMode.externalApplication);
|
||||
// 复制到剪贴板
|
||||
Utils.copyText(
|
||||
_loginPageCtr.codeInfo.value['data']?['url'] ?? '',
|
||||
@@ -387,7 +366,6 @@ class _LoginPageState extends State<LoginPage> {
|
||||
});
|
||||
},
|
||||
value: item,
|
||||
// height: menuItemHeight,
|
||||
child: Row(children: [
|
||||
Text(item['cname']),
|
||||
const Spacer(),
|
||||
@@ -400,7 +378,7 @@ class _LoginPageState extends State<LoginPage> {
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
SizedBox(
|
||||
height: 24, // 这里设置固定高度
|
||||
height: 24,
|
||||
child: VerticalDivider(
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
|
||||
@@ -97,17 +97,24 @@ class MainController extends GetxController {
|
||||
if ((shouldCheckPM.not && res.firstOrNull?['status'] == true) ||
|
||||
(shouldCheckPM && res.getOrNull(1)?['status'] == true)) {
|
||||
int index = shouldCheckPM.not ? 0 : 1;
|
||||
if (msgUnReadTypes.contains(MsgUnReadType.reply)) {
|
||||
count += (res[index]['data']['reply'] as int?) ?? 0;
|
||||
}
|
||||
if (msgUnReadTypes.contains(MsgUnReadType.at)) {
|
||||
count += (res[index]['data']['at'] as int?) ?? 0;
|
||||
}
|
||||
if (msgUnReadTypes.contains(MsgUnReadType.like)) {
|
||||
count += (res[index]['data']['like'] as int?) ?? 0;
|
||||
}
|
||||
if (msgUnReadTypes.contains(MsgUnReadType.sysMsg)) {
|
||||
count += (res[index]['data']['sys_msg'] as int?) ?? 0;
|
||||
dynamic data = res[index]['data'];
|
||||
for (final item in msgUnReadTypes) {
|
||||
switch (item) {
|
||||
case MsgUnReadType.pm:
|
||||
break;
|
||||
case MsgUnReadType.reply:
|
||||
count += (data['reply'] as int?) ?? 0;
|
||||
break;
|
||||
case MsgUnReadType.at:
|
||||
count += (data['at'] as int?) ?? 0;
|
||||
break;
|
||||
case MsgUnReadType.like:
|
||||
count += (data['like'] as int?) ?? 0;
|
||||
break;
|
||||
case MsgUnReadType.sysMsg:
|
||||
count += (data['sys_msg'] as int?) ?? 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
count = count == 0
|
||||
@@ -176,7 +183,7 @@ class MainController extends GetxController {
|
||||
|
||||
void setCount([int count = 0]) async {
|
||||
if (dynIndex == -1 || navigationBars[dynIndex]['count'] == count) return;
|
||||
navigationBars[dynIndex]['count'] = count; // 修改 count 属性为新的值
|
||||
navigationBars[dynIndex]['count'] = count;
|
||||
navigationBars.refresh();
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ class _MainAppState extends State<MainApp>
|
||||
late final _homeController = Get.put(HomeController());
|
||||
late final _dynamicController = Get.put(DynamicsController());
|
||||
|
||||
late int _lastSelectTime = 0; //上次点击时间
|
||||
late int _lastSelectTime = 0;
|
||||
late bool enableMYBar;
|
||||
late bool useSideBar;
|
||||
|
||||
@@ -192,7 +192,7 @@ class _MainAppState extends State<MainApp>
|
||||
value: SystemUiOverlayStyle(
|
||||
systemNavigationBarColor: Colors.transparent,
|
||||
systemNavigationBarIconBrightness:
|
||||
Theme.of(context).brightness.reverse, // 设置虚拟按键图标颜色
|
||||
Theme.of(context).brightness.reverse,
|
||||
),
|
||||
child: Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
@@ -412,11 +412,6 @@ class _MainAppState extends State<MainApp>
|
||||
? Text(count.toString())
|
||||
: null,
|
||||
padding: const EdgeInsets.fromLTRB(6, 0, 6, 0),
|
||||
// isLabelVisible:
|
||||
// _mainController.dynamicBadgeType != DynamicBadgeMode.hidden &&
|
||||
// count > 0,
|
||||
// backgroundColor: Theme.of(context).colorScheme.primary,
|
||||
// textColor: Theme.of(context).colorScheme.onInverseSurface,
|
||||
child: icon,
|
||||
)
|
||||
: icon;
|
||||
|
||||
@@ -34,14 +34,15 @@ class MediaController
|
||||
{
|
||||
'icon': Icons.create_outlined,
|
||||
'title': '创作中心',
|
||||
'onTap': () => Get.toNamed('/webview', parameters: {
|
||||
'url': 'https://member.bilibili.com/platform/home',
|
||||
'type': 'url',
|
||||
'pageTitle': "创作中心(建议浏览器打开)",
|
||||
}),
|
||||
'onTap': () => Get.toNamed(
|
||||
'/webview',
|
||||
parameters: {
|
||||
'url': 'https://member.bilibili.com/platform/home',
|
||||
},
|
||||
),
|
||||
},
|
||||
];
|
||||
dynamic mid;
|
||||
int? mid;
|
||||
RxInt count = (-1).obs;
|
||||
|
||||
@override
|
||||
|
||||
@@ -45,61 +45,58 @@ class _MediaPageState extends CommonPageState<MediaPage, MediaController>
|
||||
appBar: AppBar(
|
||||
toolbarHeight: 30,
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
body: ListView(
|
||||
controller: controller.scrollController,
|
||||
child: Column(
|
||||
children: [
|
||||
ListTile(
|
||||
leading: null,
|
||||
title: Padding(
|
||||
padding: const EdgeInsets.only(left: 20),
|
||||
child: Text(
|
||||
'媒体库',
|
||||
style: TextStyle(
|
||||
fontSize:
|
||||
Theme.of(context).textTheme.titleLarge!.fontSize,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
trailing: IconButton(
|
||||
tooltip: '设置',
|
||||
onPressed: () {
|
||||
Get.toNamed('/setting');
|
||||
},
|
||||
icon: const Icon(
|
||||
Icons.settings_outlined,
|
||||
size: 20,
|
||||
),
|
||||
)),
|
||||
for (var i in controller.list) ...[
|
||||
ListTile(
|
||||
onTap: () => i['onTap'](),
|
||||
dense: true,
|
||||
leading: Padding(
|
||||
padding: const EdgeInsets.only(left: 15),
|
||||
child: Icon(
|
||||
i['icon'],
|
||||
color: primary,
|
||||
),
|
||||
),
|
||||
contentPadding:
|
||||
const EdgeInsets.only(left: 15, top: 2, bottom: 2),
|
||||
minLeadingWidth: 0,
|
||||
title: Text(
|
||||
i['title'],
|
||||
style: const TextStyle(fontSize: 15),
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
children: [
|
||||
ListTile(
|
||||
leading: null,
|
||||
title: Padding(
|
||||
padding: const EdgeInsets.only(left: 20),
|
||||
child: Text(
|
||||
'媒体库',
|
||||
style: TextStyle(
|
||||
fontSize: Theme.of(context).textTheme.titleLarge!.fontSize,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
],
|
||||
Obx(
|
||||
() => controller.loadingState.value is Loading
|
||||
? const SizedBox.shrink()
|
||||
: favFolder(),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
trailing: IconButton(
|
||||
tooltip: '设置',
|
||||
onPressed: () {
|
||||
Get.toNamed('/setting');
|
||||
},
|
||||
icon: const Icon(
|
||||
Icons.settings_outlined,
|
||||
size: 20,
|
||||
),
|
||||
),
|
||||
),
|
||||
for (var item in controller.list)
|
||||
ListTile(
|
||||
onTap: item['onTap'],
|
||||
dense: true,
|
||||
leading: Padding(
|
||||
padding: const EdgeInsets.only(left: 15),
|
||||
child: Icon(
|
||||
item['icon'],
|
||||
color: primary,
|
||||
),
|
||||
),
|
||||
contentPadding:
|
||||
const EdgeInsets.only(left: 15, top: 2, bottom: 2),
|
||||
minLeadingWidth: 0,
|
||||
title: Text(
|
||||
item['title'],
|
||||
style: const TextStyle(fontSize: 15),
|
||||
),
|
||||
),
|
||||
Obx(
|
||||
() => controller.loadingState.value is Loading
|
||||
? const SizedBox.shrink()
|
||||
: favFolder(),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -118,7 +115,6 @@ class _MediaPageState extends CommonPageState<MediaPage, MediaController>
|
||||
controller.onRefresh();
|
||||
});
|
||||
},
|
||||
leading: null,
|
||||
dense: true,
|
||||
title: Padding(
|
||||
padding: const EdgeInsets.only(left: 10),
|
||||
@@ -143,11 +139,12 @@ class _MediaPageState extends CommonPageState<MediaPage, MediaController>
|
||||
),
|
||||
),
|
||||
WidgetSpan(
|
||||
child: Icon(
|
||||
Icons.arrow_forward_ios,
|
||||
size: 18,
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
)),
|
||||
child: Icon(
|
||||
Icons.arrow_forward_ios,
|
||||
size: 18,
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -156,21 +153,15 @@ class _MediaPageState extends CommonPageState<MediaPage, MediaController>
|
||||
trailing: IconButton(
|
||||
tooltip: '刷新',
|
||||
onPressed: controller.onRefresh,
|
||||
icon: const Icon(
|
||||
Icons.refresh,
|
||||
size: 20,
|
||||
),
|
||||
icon: const Icon(Icons.refresh, size: 20),
|
||||
),
|
||||
),
|
||||
// const SizedBox(height: 10),
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
height: MediaQuery.textScalerOf(context).scale(200),
|
||||
height: 200,
|
||||
child: Obx(() => _buildBody(controller.loadingState.value)),
|
||||
),
|
||||
SizedBox(
|
||||
height: MediaQuery.paddingOf(context).bottom + 100,
|
||||
),
|
||||
const SizedBox(height: 100),
|
||||
],
|
||||
);
|
||||
}
|
||||
@@ -251,7 +242,7 @@ class _MediaPageState extends CommonPageState<MediaPage, MediaController>
|
||||
),
|
||||
);
|
||||
}
|
||||
return const SizedBox();
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -297,9 +288,9 @@ class FavFolderItem extends StatelessWidget {
|
||||
.colorScheme
|
||||
.onInverseSurface
|
||||
.withOpacity(0.4),
|
||||
offset: const Offset(4, -12), // 阴影与容器的距离
|
||||
blurRadius: 0.0, // 高斯的标准偏差与盒子的形状卷积。
|
||||
spreadRadius: 0.0, // 在应用模糊之前,框应该膨胀的量。
|
||||
offset: const Offset(4, -12),
|
||||
blurRadius: 0.0,
|
||||
spreadRadius: 0.0,
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@@ -128,7 +128,6 @@ class _MemberPageNewState extends State<MemberPageNew> {
|
||||
children: _userController.tab2!.map((item) {
|
||||
return switch (item.param!) {
|
||||
'home' => MemberHome(heroTag: _heroTag),
|
||||
// 'dynamic' => MemberDynamic(mid: _mid ?? -1),
|
||||
'dynamic' => MemberDynamicsPage(mid: _mid),
|
||||
'contribute' => Obx(
|
||||
() => MemberContribute(
|
||||
|
||||
@@ -189,15 +189,6 @@ class _EditProfilePageState extends State<EditProfilePage> {
|
||||
onTap: () =>
|
||||
Utils.copyText(loadingState.response['mid'].toString()),
|
||||
),
|
||||
// _divider,
|
||||
// _item(
|
||||
// title: '二维码名片',
|
||||
// widget: Icon(
|
||||
// Icons.qr_code,
|
||||
// color: Theme.of(context).colorScheme.outline,
|
||||
// ),
|
||||
// onTap: () {},
|
||||
// ),
|
||||
_divider1,
|
||||
_item(
|
||||
title: '哔哩哔哩认证',
|
||||
|
||||
@@ -135,44 +135,19 @@ class UserInfoCard extends StatelessWidget {
|
||||
),
|
||||
if (card.vip?.vipStatus == 1) ...[
|
||||
const SizedBox(width: 8),
|
||||
Image.network(
|
||||
card.vip!.label!.image!.http2https,
|
||||
CachedNetworkImage(
|
||||
imageUrl: Utils.thumbnailImgUrl(
|
||||
card.vip!.label!.image!.http2https),
|
||||
height: 20,
|
||||
),
|
||||
],
|
||||
if (card.nameplate?.image?.isNotEmpty == true) ...[
|
||||
const SizedBox(width: 8),
|
||||
Image.network(
|
||||
card.nameplate!.image!.http2https,
|
||||
CachedNetworkImage(
|
||||
imageUrl: Utils.thumbnailImgUrl(card.nameplate!.image!),
|
||||
height: 20,
|
||||
),
|
||||
],
|
||||
// GestureDetector(
|
||||
// onTap: () {
|
||||
// Utils.copyText(card.mid.toString());
|
||||
// },
|
||||
// child: Container(
|
||||
// padding:
|
||||
// const EdgeInsets.symmetric(horizontal: 8, vertical: 2.5),
|
||||
// decoration: BoxDecoration(
|
||||
// color: Theme.of(context).colorScheme.secondaryContainer,
|
||||
// borderRadius: const BorderRadius.all(Radius.circular(12)),
|
||||
// ),
|
||||
// child: Text(
|
||||
// 'uid: ${card.mid}',
|
||||
// style: TextStyle(
|
||||
// height: 1,
|
||||
// fontSize: 12,
|
||||
// color: Theme.of(context).colorScheme.onSecondaryContainer,
|
||||
// ),
|
||||
// strutStyle: const StrutStyle(
|
||||
// height: 1,
|
||||
// leading: 0,
|
||||
// fontSize: 12,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@@ -55,18 +55,22 @@ class _MemberSearchPageState extends State<MemberSearchPage> {
|
||||
() => _memberSearchCtr.hasData.value
|
||||
? Column(
|
||||
children: [
|
||||
Obx(
|
||||
() => TabBar(
|
||||
controller: _memberSearchCtr.tabController,
|
||||
tabs: [
|
||||
Tab(
|
||||
text:
|
||||
'视频 ${_memberSearchCtr.archiveCount.value != -1 ? '${_memberSearchCtr.archiveCount.value}' : ''}'),
|
||||
Tab(
|
||||
text:
|
||||
'动态 ${_memberSearchCtr.dynamicCount.value != -1 ? '${_memberSearchCtr.dynamicCount.value}' : ''}'),
|
||||
],
|
||||
),
|
||||
TabBar(
|
||||
controller: _memberSearchCtr.tabController,
|
||||
tabs: [
|
||||
Obx(
|
||||
() => Tab(
|
||||
text:
|
||||
'视频 ${_memberSearchCtr.archiveCount.value != -1 ? '${_memberSearchCtr.archiveCount.value}' : ''}',
|
||||
),
|
||||
),
|
||||
Obx(
|
||||
() => Tab(
|
||||
text:
|
||||
'动态 ${_memberSearchCtr.dynamicCount.value != -1 ? '${_memberSearchCtr.dynamicCount.value}' : ''}',
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Expanded(
|
||||
child: tabBarView(
|
||||
|
||||
@@ -154,8 +154,6 @@ class MineController extends GetxController {
|
||||
],
|
||||
),
|
||||
),
|
||||
// duration: const Duration(seconds: 2),
|
||||
// showCloseIcon: true,
|
||||
);
|
||||
},
|
||||
).then((res) {
|
||||
@@ -200,6 +198,9 @@ class MineController extends GetxController {
|
||||
|
||||
onChangeTheme() {
|
||||
themeType.value = nextThemeType;
|
||||
try {
|
||||
Get.find<MineController>().themeType.value = themeType.value;
|
||||
} catch (_) {}
|
||||
setting.put(SettingBoxKey.themeMode, themeType.value.code);
|
||||
Get.changeThemeMode(themeType.value.toThemeMode);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import 'package:PiliPlus/utils/storage.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:PiliPlus/common/constants.dart';
|
||||
@@ -17,7 +16,6 @@ class MinePage extends StatefulWidget {
|
||||
|
||||
class _MinePageState extends State<MinePage> {
|
||||
final MineController _mineController = Get.put(MineController())
|
||||
..themeType.value = ThemeType.values[GStorage.themeTypeInt]
|
||||
..queryUserInfo();
|
||||
|
||||
Widget get _header => FittedBox(
|
||||
@@ -40,8 +38,7 @@ class _MinePageState extends State<MinePage> {
|
||||
iconSize: 40.0,
|
||||
padding: const EdgeInsets.all(8),
|
||||
style: const ButtonStyle(
|
||||
tapTargetSize:
|
||||
MaterialTapTargetSize.shrinkWrap, // the '2023' part
|
||||
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
||||
),
|
||||
tooltip: "${MineController.anonymity.value ? '退出' : '进入'}无痕模式",
|
||||
onPressed: () {
|
||||
@@ -61,8 +58,7 @@ class _MinePageState extends State<MinePage> {
|
||||
iconSize: 40.0,
|
||||
padding: const EdgeInsets.all(8),
|
||||
style: const ButtonStyle(
|
||||
tapTargetSize:
|
||||
MaterialTapTargetSize.shrinkWrap, // the '2023' part
|
||||
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
||||
),
|
||||
tooltip: '切换至${_mineController.nextThemeType.description}主题',
|
||||
onPressed: _mineController.onChangeTheme,
|
||||
@@ -77,8 +73,7 @@ class _MinePageState extends State<MinePage> {
|
||||
iconSize: 40.0,
|
||||
padding: const EdgeInsets.all(8),
|
||||
style: const ButtonStyle(
|
||||
tapTargetSize:
|
||||
MaterialTapTargetSize.shrinkWrap, // the '2023' part
|
||||
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
||||
),
|
||||
tooltip: '设置',
|
||||
onPressed: () => {
|
||||
|
||||
@@ -159,7 +159,6 @@ class _SysMsgPageState extends State<SysMsgPage> {
|
||||
} else if (matchStr.startsWith('【')) {
|
||||
try {
|
||||
bool isBV = match[3]?.startsWith('BV') == true;
|
||||
// validate
|
||||
if (isBV) {
|
||||
IdUtils.bv2av(match[3]!);
|
||||
} else {
|
||||
|
||||
@@ -9,6 +9,9 @@ import 'package:PiliPlus/utils/storage.dart';
|
||||
import 'package:get/get_rx/src/rx_workers/utils/debouncer.dart';
|
||||
|
||||
class SSearchController extends GetxController {
|
||||
SSearchController(this.tag);
|
||||
final String tag;
|
||||
|
||||
final searchFocusNode = FocusNode();
|
||||
final controller = TextEditingController();
|
||||
|
||||
@@ -115,6 +118,7 @@ class SSearchController extends GetxController {
|
||||
await Get.toNamed(
|
||||
'/searchResult',
|
||||
parameters: {
|
||||
'tag': tag,
|
||||
'keyword': controller.text,
|
||||
},
|
||||
arguments: {
|
||||
|
||||
@@ -21,7 +21,7 @@ class SearchPage extends StatefulWidget {
|
||||
class _SearchPageState extends State<SearchPage> {
|
||||
final _tag = Utils.generateRandomString(6);
|
||||
late final SSearchController _searchController = Get.put(
|
||||
SSearchController(),
|
||||
SSearchController(_tag),
|
||||
tag: _tag,
|
||||
);
|
||||
|
||||
@@ -67,7 +67,6 @@ class _SearchPageState extends State<SearchPage> {
|
||||
controller: _searchController.controller,
|
||||
textInputAction: TextInputAction.search,
|
||||
onChanged: _searchController.onChange,
|
||||
// textAlignVertical: TextAlignVertical.center,
|
||||
decoration: InputDecoration(
|
||||
hintText: _searchController.hintText,
|
||||
border: InputBorder.none,
|
||||
|
||||
@@ -24,6 +24,7 @@ class _SearchResultPageState extends State<SearchResultPage>
|
||||
late TabController _tabController;
|
||||
final String _tag = DateTime.now().millisecondsSinceEpoch.toString();
|
||||
final bool? _isFromSearch = Get.arguments?['fromSearch'];
|
||||
SSearchController? sSearchController;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -35,21 +36,21 @@ class _SearchResultPageState extends State<SearchResultPage>
|
||||
|
||||
_tabController = TabController(
|
||||
vsync: this,
|
||||
initialIndex: Get.arguments?['initIndex'] != null
|
||||
? (Get.arguments?['initIndex'] as int)
|
||||
: 0,
|
||||
initialIndex: Get.arguments?['initIndex'] ?? 0,
|
||||
length: SearchType.values.length,
|
||||
);
|
||||
|
||||
if (Get.arguments is int) {
|
||||
if (_isFromSearch == true) {
|
||||
try {
|
||||
sSearchController =
|
||||
Get.find<SSearchController>(tag: Get.parameters['tag']);
|
||||
} catch (_) {}
|
||||
_tabController.addListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
void listener() {
|
||||
if (Get.isRegistered<SSearchController>()) {
|
||||
Get.find<SSearchController>().initIndex = _tabController.index;
|
||||
}
|
||||
sSearchController?.initIndex = _tabController.index;
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:PiliPlus/models/common/nav_bar_config.dart';
|
||||
import 'package:PiliPlus/models/common/theme_type.dart';
|
||||
import 'package:PiliPlus/pages/home/index.dart';
|
||||
import 'package:PiliPlus/pages/mine/controller.dart';
|
||||
import 'package:PiliPlus/pages/setting/widgets/select_dialog.dart';
|
||||
import 'package:flex_seed_scheme/flex_seed_scheme.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -67,6 +68,9 @@ class _ColorSelectPageState extends State<ColorSelectPage> {
|
||||
},
|
||||
);
|
||||
if (result != null) {
|
||||
try {
|
||||
Get.find<MineController>().themeType.value = result;
|
||||
} catch (_) {}
|
||||
ctr.themeType.value = result;
|
||||
GStorage.setting.put(SettingBoxKey.themeMode, result.index);
|
||||
Get.changeThemeMode(result.toThemeMode);
|
||||
|
||||
@@ -12,7 +12,6 @@ class FontSizeSelectPage extends StatefulWidget {
|
||||
|
||||
class _FontSizeSelectPageState extends State<FontSizeSelectPage> {
|
||||
List<double> list = List.generate(16, (index) => 0.85 + index * 0.05);
|
||||
//[0.85, 0.9, 0.95, 1.0, 1.05, 1.1, 1.15, 1.2, 1.25, 1.3, 1.35];
|
||||
late double minSize;
|
||||
late double maxSize;
|
||||
late double currentSize;
|
||||
|
||||
@@ -63,7 +63,7 @@ class _LogsPageState extends State<LogsPage> {
|
||||
if (l.startsWith("Crash occurred on")) {
|
||||
try {
|
||||
date = DateTime.parse(
|
||||
l.split("Crash occurred on")[1].trim(), //.split('.')[0],
|
||||
l.split("Crash occurred on")[1].trim(),
|
||||
);
|
||||
} catch (e) {
|
||||
debugPrint(e.toString());
|
||||
@@ -111,7 +111,6 @@ class _LogsPageState extends State<LogsPage> {
|
||||
actions: [
|
||||
PopupMenuButton<String>(
|
||||
onSelected: (String type) {
|
||||
// 处理菜单项选择的逻辑
|
||||
switch (type) {
|
||||
case 'copy':
|
||||
copyLogs();
|
||||
|
||||
@@ -82,7 +82,6 @@ class _PlaySpeedPageState extends State<PlaySpeedPage> {
|
||||
content: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
// const Text('输入你想要的视频倍速,例如:1.0'),
|
||||
const SizedBox(height: 12),
|
||||
TextField(
|
||||
autofocus: true,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import 'package:PiliPlus/http/login.dart';
|
||||
import 'package:PiliPlus/pages/about/index.dart';
|
||||
import 'package:PiliPlus/pages/about/view.dart';
|
||||
import 'package:PiliPlus/pages/login/controller.dart';
|
||||
import 'package:PiliPlus/pages/setting/extra_setting.dart';
|
||||
import 'package:PiliPlus/pages/setting/play_setting.dart';
|
||||
|
||||
@@ -131,10 +131,8 @@ List<SettingsModel> get styleSettings => [
|
||||
onChanged: (value) {
|
||||
if (value) {
|
||||
autoScreen();
|
||||
// SmartDialog.showToast('已开启横屏适配');
|
||||
} else {
|
||||
AutoOrientation.portraitUpMode();
|
||||
// SmartDialog.showToast('已关闭横屏适配');
|
||||
}
|
||||
}),
|
||||
SettingsModel(
|
||||
@@ -536,6 +534,9 @@ List<SettingsModel> get styleSettings => [
|
||||
},
|
||||
);
|
||||
if (result != null) {
|
||||
try {
|
||||
Get.find<MineController>().themeType.value = result;
|
||||
} catch (_) {}
|
||||
GStorage.setting.put(SettingBoxKey.themeMode, result.index);
|
||||
Get.put(ColorSelectController()).themeType.value = result;
|
||||
Get.changeThemeMode(result.toThemeMode);
|
||||
|
||||
@@ -133,7 +133,7 @@ class _SetSwitchItemState extends State<SetSwitchItem> {
|
||||
: null,
|
||||
leading: widget.leading,
|
||||
trailing: Transform.scale(
|
||||
alignment: Alignment.centerRight, // 缩放Switch的大小后保持右侧对齐, 避免右侧空隙过大
|
||||
alignment: Alignment.centerRight,
|
||||
scale: 0.8,
|
||||
child: Switch(
|
||||
thumbIcon:
|
||||
@@ -141,7 +141,7 @@ class _SetSwitchItemState extends State<SetSwitchItem> {
|
||||
if (states.isNotEmpty && states.first == WidgetState.selected) {
|
||||
return const Icon(Icons.done);
|
||||
}
|
||||
return null; // All other states will use the default thumbIcon.
|
||||
return null;
|
||||
}),
|
||||
value: val,
|
||||
onChanged: switchChange,
|
||||
|
||||
@@ -102,7 +102,6 @@ class VideoDetailController extends GetxController
|
||||
|
||||
Box get setting => GStorage.setting;
|
||||
|
||||
// late bool enableCDN;
|
||||
int? cacheVideoQa;
|
||||
late String cacheDecode;
|
||||
late String cacheSecondDecode;
|
||||
@@ -285,14 +284,10 @@ class VideoDetailController extends GetxController
|
||||
}
|
||||
danmakuCid.value = cid.value;
|
||||
|
||||
///
|
||||
if (Platform.isAndroid) {
|
||||
floating = Floating();
|
||||
}
|
||||
|
||||
// CDN优化
|
||||
// enableCDN = setting.get(SettingBoxKey.enableCDN, defaultValue: true);
|
||||
|
||||
// 预设的解码格式
|
||||
cacheDecode = setting.get(SettingBoxKey.defaultDecode,
|
||||
defaultValue: VideoDecodeFormats.values.last.code);
|
||||
@@ -1003,7 +998,6 @@ class VideoDetailController extends GetxController
|
||||
}
|
||||
|
||||
/// 更新画质、音质
|
||||
/// TODO 继续进度播放
|
||||
updatePlayer() {
|
||||
isShowCover.value = false;
|
||||
playedTime = plPlayerController.position.value;
|
||||
@@ -1280,9 +1274,6 @@ class VideoDetailController extends GetxController
|
||||
orElse: () => videosList.first);
|
||||
setVideoHeight();
|
||||
|
||||
// videoUrl = enableCDN
|
||||
// ? VideoUtils.getCdnUrl(firstVideo)
|
||||
// : (firstVideo.backupUrl ?? firstVideo.baseUrl!);
|
||||
videoUrl = VideoUtils.getCdnUrl(firstVideo);
|
||||
|
||||
/// 优先顺序 设置中指定质量 -> 当前可选的最高质量
|
||||
@@ -1308,9 +1299,6 @@ class VideoDetailController extends GetxController
|
||||
}
|
||||
firstAudio = audiosList.firstWhere((e) => e.id == closestNumber,
|
||||
orElse: () => audiosList.first);
|
||||
// audioUrl = enableCDN
|
||||
// ? VideoUtils.getCdnUrl(firstAudio)
|
||||
// : (firstAudio.backupUrl ?? firstAudio.baseUrl!);
|
||||
audioUrl = VideoUtils.getCdnUrl(firstAudio);
|
||||
if (firstAudio.id != null) {
|
||||
currentAudioQa = AudioQualityCode.fromCode(firstAudio.id!)!;
|
||||
@@ -1470,9 +1458,6 @@ class VideoDetailController extends GetxController
|
||||
|
||||
Future _querySubtitles() async {
|
||||
var res = await VideoHttp.subtitlesJson(bvid: bvid, cid: cid.value);
|
||||
// if (!res["status"]) {
|
||||
// SmartDialog.showToast('查询字幕错误,${res["msg"]}');
|
||||
// }
|
||||
if (res['status']) {
|
||||
// interactive video
|
||||
if (graphVersion == null) {
|
||||
|
||||
@@ -176,11 +176,6 @@ class VideoIntroController extends GetxController {
|
||||
lastPlayCid.value == 0) {
|
||||
lastPlayCid.value = videoDetail.value.pages!.first.cid!;
|
||||
}
|
||||
// Get.find<VideoDetailController>(tag: heroTag).tabs.value = [
|
||||
// '简介',
|
||||
// '评论 ${result['data']!.stat!.reply}'
|
||||
// ];
|
||||
// 获取到粉丝数再返回
|
||||
queryUserStat();
|
||||
} else {
|
||||
SmartDialog.showToast(
|
||||
@@ -274,12 +269,10 @@ class VideoIntroController extends GetxController {
|
||||
return;
|
||||
}
|
||||
if (videoDetail.value.stat?.like == null) {
|
||||
// not init
|
||||
return;
|
||||
}
|
||||
var result = await VideoHttp.likeVideo(bvid: bvid, type: !hasLike.value);
|
||||
if (result['status']) {
|
||||
// hasLike.value = result["data"] == 1 ? true : false;
|
||||
if (!hasLike.value) {
|
||||
SmartDialog.showToast(result['data']['toast']);
|
||||
hasLike.value = true;
|
||||
@@ -303,7 +296,6 @@ class VideoIntroController extends GetxController {
|
||||
var result =
|
||||
await VideoHttp.dislikeVideo(bvid: bvid, type: !hasDislike.value);
|
||||
if (result['status']) {
|
||||
// hasLike.value = result["data"] == 1 ? true : false;
|
||||
if (!hasDislike.value) {
|
||||
SmartDialog.showToast('点踩成功');
|
||||
hasDislike.value = true;
|
||||
@@ -312,7 +304,6 @@ class VideoIntroController extends GetxController {
|
||||
SmartDialog.showToast('取消踩');
|
||||
hasDislike.value = false;
|
||||
}
|
||||
// hasDislike.refresh();
|
||||
} else {
|
||||
SmartDialog.showToast(result['msg']);
|
||||
}
|
||||
@@ -435,8 +426,6 @@ class VideoIntroController extends GetxController {
|
||||
Get.back();
|
||||
hasFav.value =
|
||||
addMediaIdsNew.isNotEmpty || favIds?.length != delMediaIdsNew.length;
|
||||
// 重新获取收藏状态
|
||||
// await queryHasFavVideo();
|
||||
SmartDialog.showToast('操作成功');
|
||||
} else {
|
||||
SmartDialog.showToast(result['msg']);
|
||||
@@ -581,14 +570,6 @@ class VideoIntroController extends GetxController {
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
// MemberController _ = Get.put<MemberController>(MemberController(mid: mid),
|
||||
// tag: mid.toString());
|
||||
// await _.getInfo();
|
||||
// if (context.mounted) await _.actionRelationMod(context);
|
||||
// followStatus['attribute'] = _.attribute.value;
|
||||
// followStatus.refresh();
|
||||
// Get.delete<MemberController>(tag: mid.toString());
|
||||
}
|
||||
|
||||
// 修改分P或番剧分集
|
||||
@@ -678,10 +659,6 @@ class VideoIntroController extends GetxController {
|
||||
bvid: bvid,
|
||||
cid: lastPlayCid.value,
|
||||
);
|
||||
// dynamic result = await GrpcRepo.playerOnline(
|
||||
// aid: IdUtils.bv2av(bvid),
|
||||
// cid: lastPlayCid.value,
|
||||
// );
|
||||
if (result['status']) {
|
||||
total.value = result['data'];
|
||||
}
|
||||
|
||||
@@ -53,7 +53,6 @@ class _VideoIntroPanelState extends State<VideoIntroPanel>
|
||||
with AutomaticKeepAliveClientMixin {
|
||||
late VideoIntroController videoIntroController;
|
||||
|
||||
// 添加页面缓存
|
||||
@override
|
||||
bool get wantKeepAlive => true;
|
||||
|
||||
@@ -240,7 +239,6 @@ class _VideoInfoState extends State<VideoInfo> {
|
||||
return;
|
||||
}
|
||||
feedBack();
|
||||
// widget.showIntroDetail();
|
||||
videoIntroController.expandableCtr?.toggle();
|
||||
}
|
||||
|
||||
@@ -255,16 +253,8 @@ class _VideoInfoState extends State<VideoInfo> {
|
||||
_horizontalMemberPage) {
|
||||
widget.onShowMemberPage(mid);
|
||||
} else {
|
||||
// memberHeroTag = Utils.makeHeroTag(mid);
|
||||
// String face = !loadingStatus
|
||||
// ? videoDetail.owner!.face
|
||||
// : videoItem['owner'].face;
|
||||
Get.toNamed(
|
||||
'/member?mid=$mid&from_view_aid=${videoDetailCtr.oid.value}',
|
||||
// arguments: {
|
||||
// 'face': face,
|
||||
// 'heroTag': memberHeroTag,
|
||||
// },
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -272,7 +262,7 @@ class _VideoInfoState extends State<VideoInfo> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final ThemeData t = Theme.of(context);
|
||||
final ThemeData themeData = Theme.of(context);
|
||||
return SliverLayoutBuilder(
|
||||
builder: (BuildContext context, SliverConstraints constraints) {
|
||||
bool isHorizontal = context.orientation == Orientation.landscape &&
|
||||
@@ -296,298 +286,271 @@ class _VideoInfoState extends State<VideoInfo> {
|
||||
onTap: () {},
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: videoItem['staff'] == null
|
||||
? Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
if (videoItem['staff'] == null) ...[
|
||||
Expanded(
|
||||
child: Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: GestureDetector(
|
||||
onTap: onPushMember,
|
||||
behavior: HitTestBehavior.opaque,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: onPushMember,
|
||||
behavior: HitTestBehavior.opaque,
|
||||
child: Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
Obx(
|
||||
() => Stack(
|
||||
clipBehavior: Clip.none,
|
||||
children: [
|
||||
Obx(
|
||||
() => Stack(
|
||||
clipBehavior: Clip.none,
|
||||
children: [
|
||||
NetworkImgLayer(
|
||||
type: 'avatar',
|
||||
src: videoIntroController
|
||||
.userStat
|
||||
NetworkImgLayer(
|
||||
type: 'avatar',
|
||||
src: videoIntroController.userStat
|
||||
.value['card']?['face'] ??
|
||||
'',
|
||||
width: 35,
|
||||
height: 35,
|
||||
fadeInDuration: Duration.zero,
|
||||
fadeOutDuration: Duration.zero,
|
||||
),
|
||||
if ((videoIntroController.userStat
|
||||
.value['card']
|
||||
?['face'] ??
|
||||
'',
|
||||
width: 35,
|
||||
height: 35,
|
||||
fadeInDuration: Duration.zero,
|
||||
fadeOutDuration:
|
||||
Duration.zero,
|
||||
?['official_verify']
|
||||
?['type'] ??
|
||||
-1) !=
|
||||
-1)
|
||||
Positioned(
|
||||
right: -2,
|
||||
bottom: -2,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.surface,
|
||||
),
|
||||
if ((videoIntroController
|
||||
.userStat
|
||||
.value['card']
|
||||
?[
|
||||
'official_verify']
|
||||
?['type'] ??
|
||||
-1) !=
|
||||
-1)
|
||||
Positioned(
|
||||
right: -2,
|
||||
bottom: -2,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.surface,
|
||||
),
|
||||
child: Icon(
|
||||
Icons.offline_bolt,
|
||||
color: videoIntroController
|
||||
.userStat
|
||||
.value['card']
|
||||
?[
|
||||
'official_verify']
|
||||
?['type'] ==
|
||||
0
|
||||
? Colors.yellow
|
||||
: Colors
|
||||
.lightBlueAccent,
|
||||
size: 14,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
child: Icon(
|
||||
Icons.offline_bolt,
|
||||
color: videoIntroController
|
||||
.userStat
|
||||
.value['card']
|
||||
?[
|
||||
'official_verify']
|
||||
?['type'] ==
|
||||
0
|
||||
? Colors.yellow
|
||||
: Colors.lightBlueAccent,
|
||||
size: 14,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Column(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Obx(
|
||||
() => Text(
|
||||
videoIntroController.userStat
|
||||
.value['card']
|
||||
?['name'] ??
|
||||
"",
|
||||
maxLines: 1,
|
||||
overflow:
|
||||
TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: (videoIntroController
|
||||
.userStat
|
||||
.value['card']?['vip']
|
||||
?[
|
||||
'status'] ??
|
||||
-1) >
|
||||
0 &&
|
||||
videoIntroController
|
||||
.userStat
|
||||
.value['card']
|
||||
?[
|
||||
'vip']?['type'] ==
|
||||
2
|
||||
? context.vipColor
|
||||
: null,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 0),
|
||||
Obx(
|
||||
() => Text(
|
||||
'${Utils.numFormat(videoIntroController.userStat.value['follower'])}粉丝 ${videoIntroController.userStat.value['archive_count'] != null ? '${Utils.numFormat(videoIntroController.userStat.value['archive_count'])}视频' : ''}',
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color:
|
||||
t.colorScheme.outline,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
followButton(context, t),
|
||||
],
|
||||
)
|
||||
: SelfSizedHorizontalList(
|
||||
gapSize: 25,
|
||||
itemCount: videoItem['staff'].length,
|
||||
childBuilder: (index) => GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onTap: () {
|
||||
int? ownerMid = !widget.loadingStatus
|
||||
? videoDetail.owner?.mid
|
||||
: videoItem['owner']?.mid;
|
||||
if (videoItem['staff'][index].mid ==
|
||||
ownerMid &&
|
||||
context.orientation ==
|
||||
Orientation.landscape &&
|
||||
_horizontalMemberPage) {
|
||||
widget.onShowMemberPage(ownerMid);
|
||||
} else {
|
||||
Get.toNamed(
|
||||
'/member?mid=${videoItem['staff'][index].mid}&from_view_aid=${videoDetailCtr.oid.value}',
|
||||
// arguments: {
|
||||
// 'face':
|
||||
// videoItem['staff'][index].face,
|
||||
// 'heroTag': Utils.makeHeroTag(
|
||||
// videoItem['staff'][index].mid),
|
||||
// },
|
||||
);
|
||||
}
|
||||
},
|
||||
child: Row(
|
||||
const SizedBox(width: 10),
|
||||
Column(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Stack(
|
||||
clipBehavior: Clip.none,
|
||||
children: [
|
||||
NetworkImgLayer(
|
||||
type: 'avatar',
|
||||
src: videoItem['staff'][index]
|
||||
.face,
|
||||
width: 35,
|
||||
height: 35,
|
||||
fadeInDuration: Duration.zero,
|
||||
fadeOutDuration: Duration.zero,
|
||||
),
|
||||
if ((videoItem['staff'][index]
|
||||
.official?['type'] ??
|
||||
-1) !=
|
||||
-1)
|
||||
Positioned(
|
||||
right: -2,
|
||||
bottom: -2,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.surface,
|
||||
),
|
||||
child: Icon(
|
||||
Icons.offline_bolt,
|
||||
color: videoItem['staff']
|
||||
[index]
|
||||
.official?[
|
||||
'type'] ==
|
||||
0
|
||||
? Colors.yellow
|
||||
: Colors
|
||||
.lightBlueAccent,
|
||||
size: 14,
|
||||
),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
top: 0,
|
||||
right: -6,
|
||||
child: Obx(() => videoIntroController
|
||||
.staffRelations[
|
||||
'status'] ==
|
||||
true &&
|
||||
Obx(
|
||||
() => Text(
|
||||
videoIntroController.userStat
|
||||
.value['card']?['name'] ??
|
||||
"",
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: (videoIntroController.userStat
|
||||
.value[
|
||||
'card']?['vip']
|
||||
?['status'] ??
|
||||
-1) >
|
||||
0 &&
|
||||
videoIntroController
|
||||
.staffRelations[
|
||||
'${videoItem['staff'][index].mid}'] ==
|
||||
null
|
||||
? Material(
|
||||
color: Colors.transparent,
|
||||
child: InkWell(
|
||||
customBorder:
|
||||
const CircleBorder(),
|
||||
onTap: () {
|
||||
RequestUtils
|
||||
.actionRelationMod(
|
||||
context: context,
|
||||
mid: videoItem[
|
||||
'staff']
|
||||
[index]
|
||||
.mid,
|
||||
isFollow: false,
|
||||
callback: (val) {
|
||||
videoIntroController
|
||||
.staffRelations[
|
||||
'${videoItem['staff'][index].mid}'] = true;
|
||||
},
|
||||
);
|
||||
},
|
||||
child: Ink(
|
||||
padding:
|
||||
const EdgeInsets
|
||||
.all(2),
|
||||
decoration:
|
||||
BoxDecoration(
|
||||
color: Theme.of(
|
||||
context)
|
||||
.colorScheme
|
||||
.secondaryContainer,
|
||||
shape:
|
||||
BoxShape.circle,
|
||||
),
|
||||
child: Icon(
|
||||
MdiIcons.plus,
|
||||
size: 16,
|
||||
color: Theme.of(
|
||||
context)
|
||||
.colorScheme
|
||||
.onSecondaryContainer,
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
: const SizedBox.shrink()),
|
||||
.userStat
|
||||
.value['card']
|
||||
?[
|
||||
'vip']?['type'] ==
|
||||
2
|
||||
? context.vipColor
|
||||
: null,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
videoItem['staff'][index].name,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: videoItem['staff'][index]
|
||||
.vip
|
||||
.status >
|
||||
0 &&
|
||||
videoItem['staff']
|
||||
[index]
|
||||
.vip
|
||||
.type ==
|
||||
2
|
||||
? context.vipColor
|
||||
: null,
|
||||
),
|
||||
const SizedBox(height: 0),
|
||||
Obx(
|
||||
() => Text(
|
||||
'${Utils.numFormat(videoIntroController.userStat.value['follower'])}粉丝 ${videoIntroController.userStat.value['archive_count'] != null ? '${Utils.numFormat(videoIntroController.userStat.value['archive_count'])}视频' : ''}',
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color:
|
||||
themeData.colorScheme.outline,
|
||||
),
|
||||
Text(
|
||||
videoItem['staff'][index].title,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.outline,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
followButton(context, themeData),
|
||||
] else
|
||||
Expanded(
|
||||
child: SelfSizedHorizontalList(
|
||||
gapSize: 25,
|
||||
itemCount: videoItem['staff'].length,
|
||||
childBuilder: (index) => GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onTap: () {
|
||||
int? ownerMid = !widget.loadingStatus
|
||||
? videoDetail.owner?.mid
|
||||
: videoItem['owner']?.mid;
|
||||
if (videoItem['staff'][index].mid ==
|
||||
ownerMid &&
|
||||
context.orientation ==
|
||||
Orientation.landscape &&
|
||||
_horizontalMemberPage) {
|
||||
widget.onShowMemberPage(ownerMid);
|
||||
} else {
|
||||
Get.toNamed(
|
||||
'/member?mid=${videoItem['staff'][index].mid}&from_view_aid=${videoDetailCtr.oid.value}',
|
||||
);
|
||||
}
|
||||
},
|
||||
child: Row(
|
||||
children: [
|
||||
Stack(
|
||||
clipBehavior: Clip.none,
|
||||
children: [
|
||||
NetworkImgLayer(
|
||||
type: 'avatar',
|
||||
src: videoItem['staff'][index].face,
|
||||
width: 35,
|
||||
height: 35,
|
||||
fadeInDuration: Duration.zero,
|
||||
fadeOutDuration: Duration.zero,
|
||||
),
|
||||
if ((videoItem['staff'][index]
|
||||
.official?['type'] ??
|
||||
-1) !=
|
||||
-1)
|
||||
Positioned(
|
||||
right: -2,
|
||||
bottom: -2,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.surface,
|
||||
),
|
||||
child: Icon(
|
||||
Icons.offline_bolt,
|
||||
color: videoItem['staff'][index]
|
||||
.official?[
|
||||
'type'] ==
|
||||
0
|
||||
? Colors.yellow
|
||||
: Colors.lightBlueAccent,
|
||||
size: 14,
|
||||
),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
top: 0,
|
||||
right: -6,
|
||||
child: Obx(() => videoIntroController
|
||||
.staffRelations[
|
||||
'status'] ==
|
||||
true &&
|
||||
videoIntroController
|
||||
.staffRelations[
|
||||
'${videoItem['staff'][index].mid}'] ==
|
||||
null
|
||||
? Material(
|
||||
color: Colors.transparent,
|
||||
child: InkWell(
|
||||
customBorder:
|
||||
const CircleBorder(),
|
||||
onTap: () {
|
||||
RequestUtils
|
||||
.actionRelationMod(
|
||||
context: context,
|
||||
mid: videoItem['staff']
|
||||
[index]
|
||||
.mid,
|
||||
isFollow: false,
|
||||
callback: (val) {
|
||||
videoIntroController
|
||||
.staffRelations[
|
||||
'${videoItem['staff'][index].mid}'] = true;
|
||||
},
|
||||
);
|
||||
},
|
||||
child: Ink(
|
||||
padding:
|
||||
const EdgeInsets.all(
|
||||
2),
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.secondaryContainer,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: Icon(
|
||||
MdiIcons.plus,
|
||||
size: 16,
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.onSecondaryContainer,
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
: const SizedBox.shrink()),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
videoItem['staff'][index].name,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: videoItem['staff'][index]
|
||||
.vip
|
||||
.status >
|
||||
0 &&
|
||||
videoItem['staff'][index]
|
||||
.vip
|
||||
.type ==
|
||||
2
|
||||
? context.vipColor
|
||||
: null,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
videoItem['staff'][index].title,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.outline,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (isHorizontal) ...[
|
||||
const SizedBox(width: 10),
|
||||
Expanded(
|
||||
@@ -634,7 +597,7 @@ class _VideoInfoState extends State<VideoInfo> {
|
||||
value: Utils.numFormat(!widget.loadingStatus
|
||||
? videoDetail.stat?.view ?? '-'
|
||||
: videoItem['stat']?.view ?? '-'),
|
||||
textColor: t.colorScheme.outline,
|
||||
textColor: themeData.colorScheme.outline,
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
StatDanMu(
|
||||
@@ -643,7 +606,7 @@ class _VideoInfoState extends State<VideoInfo> {
|
||||
value: Utils.numFormat(!widget.loadingStatus
|
||||
? videoDetail.stat?.danmaku ?? '-'
|
||||
: videoItem['stat']?.danmu ?? '-'),
|
||||
textColor: t.colorScheme.outline,
|
||||
textColor: themeData.colorScheme.outline,
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Text(
|
||||
@@ -654,7 +617,7 @@ class _VideoInfoState extends State<VideoInfo> {
|
||||
formatType: 'detail'),
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: t.colorScheme.outline,
|
||||
color: themeData.colorScheme.outline,
|
||||
),
|
||||
),
|
||||
if (MineController.anonymity.value) ...<Widget>[
|
||||
@@ -662,7 +625,7 @@ class _VideoInfoState extends State<VideoInfo> {
|
||||
Icon(
|
||||
MdiIcons.incognito,
|
||||
size: 15,
|
||||
color: t.colorScheme.outline,
|
||||
color: themeData.colorScheme.outline,
|
||||
semanticLabel: '无痕',
|
||||
),
|
||||
],
|
||||
@@ -673,7 +636,7 @@ class _VideoInfoState extends State<VideoInfo> {
|
||||
'${videoIntroController.total.value}人在看',
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: t.colorScheme.outline,
|
||||
color: themeData.colorScheme.outline,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -767,7 +730,6 @@ class _VideoInfoState extends State<VideoInfo> {
|
||||
SelectableText.rich(
|
||||
style: const TextStyle(
|
||||
height: 1.4,
|
||||
// fontSize: 13,
|
||||
),
|
||||
TextSpan(
|
||||
children: [
|
||||
@@ -829,16 +791,6 @@ class _VideoInfoState extends State<VideoInfo> {
|
||||
),
|
||||
),
|
||||
),
|
||||
// 点赞收藏转发 布局样式1
|
||||
// SingleChildScrollView(
|
||||
// padding: const EdgeInsets.only(top: 7, bottom: 7),
|
||||
// scrollDirection: Axis.horizontal,
|
||||
// child: actionRow(
|
||||
// context,
|
||||
// videoIntroController,
|
||||
// videoDetailCtr,
|
||||
// ),
|
||||
// ),
|
||||
// 点赞收藏转发 布局样式2
|
||||
if (!isHorizontal) ...[
|
||||
const SizedBox(height: 8),
|
||||
@@ -917,112 +869,108 @@ class _VideoInfoState extends State<VideoInfo> {
|
||||
|
||||
Widget actionGrid(
|
||||
BuildContext context, VideoIntroController videoIntroController) {
|
||||
return LayoutBuilder(
|
||||
builder: (BuildContext context, BoxConstraints constraints) {
|
||||
return Container(
|
||||
margin: const EdgeInsets.only(top: 1),
|
||||
height: 48,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: <Widget>[
|
||||
Obx(
|
||||
() => ActionItem(
|
||||
icon: const Icon(FontAwesomeIcons.thumbsUp),
|
||||
selectIcon: const Icon(FontAwesomeIcons.solidThumbsUp),
|
||||
onTap: () => handleState(videoIntroController.actionLikeVideo),
|
||||
onLongPress: () =>
|
||||
handleState(videoIntroController.actionOneThree),
|
||||
selectStatus: videoIntroController.hasLike.value,
|
||||
loadingStatus: widget.loadingStatus,
|
||||
semanticsLabel: '点赞',
|
||||
text: !widget.loadingStatus
|
||||
? Utils.numFormat(videoDetail.stat!.like!)
|
||||
: '-',
|
||||
needAnim: true,
|
||||
hasTriple: videoIntroController.hasLike.value &&
|
||||
videoIntroController.hasCoin &&
|
||||
videoIntroController.hasFav.value,
|
||||
callBack: (start) {
|
||||
if (start) {
|
||||
HapticFeedback.lightImpact();
|
||||
_coinKey.currentState?.controller?.forward();
|
||||
_favKey.currentState?.controller?.forward();
|
||||
} else {
|
||||
_coinKey.currentState?.controller?.reverse();
|
||||
_favKey.currentState?.controller?.reverse();
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
Obx(
|
||||
() => ActionItem(
|
||||
icon: const Icon(FontAwesomeIcons.thumbsDown),
|
||||
selectIcon: const Icon(FontAwesomeIcons.solidThumbsDown),
|
||||
onTap: () =>
|
||||
handleState(videoIntroController.actionDislikeVideo),
|
||||
selectStatus: videoIntroController.hasDislike.value,
|
||||
loadingStatus: widget.loadingStatus,
|
||||
semanticsLabel: '点踩',
|
||||
text: "点踩",
|
||||
),
|
||||
),
|
||||
Obx(
|
||||
() => ActionItem(
|
||||
key: _coinKey,
|
||||
icon: const Icon(FontAwesomeIcons.b),
|
||||
selectIcon: const Icon(FontAwesomeIcons.b),
|
||||
onTap: () => handleState(videoIntroController.actionCoinVideo),
|
||||
selectStatus: videoIntroController.hasCoin,
|
||||
loadingStatus: widget.loadingStatus,
|
||||
semanticsLabel: '投币',
|
||||
text: !widget.loadingStatus
|
||||
? Utils.numFormat(videoDetail.stat!.coin!)
|
||||
: '-',
|
||||
needAnim: true,
|
||||
),
|
||||
),
|
||||
Obx(
|
||||
() => ActionItem(
|
||||
key: _favKey,
|
||||
icon: const Icon(FontAwesomeIcons.star),
|
||||
selectIcon: const Icon(FontAwesomeIcons.solidStar),
|
||||
onTap: () => videoIntroController.showFavBottomSheet(context),
|
||||
onLongPress: () => videoIntroController
|
||||
.showFavBottomSheet(context, type: 'longPress'),
|
||||
selectStatus: videoIntroController.hasFav.value,
|
||||
loadingStatus: widget.loadingStatus,
|
||||
semanticsLabel: '收藏',
|
||||
text: !widget.loadingStatus
|
||||
? Utils.numFormat(videoDetail.stat!.favorite!)
|
||||
: '-',
|
||||
needAnim: true,
|
||||
),
|
||||
),
|
||||
Obx(
|
||||
() => ActionItem(
|
||||
icon: const Icon(FontAwesomeIcons.clock),
|
||||
selectIcon: const Icon(FontAwesomeIcons.solidClock),
|
||||
onTap: () => handleState(videoIntroController.viewLater),
|
||||
selectStatus: videoIntroController.hasLater.value,
|
||||
loadingStatus: widget.loadingStatus,
|
||||
semanticsLabel: '再看',
|
||||
text: '再看',
|
||||
),
|
||||
),
|
||||
ActionItem(
|
||||
icon: const Icon(FontAwesomeIcons.shareFromSquare),
|
||||
onTap: () => videoIntroController.actionShareVideo(context),
|
||||
selectStatus: false,
|
||||
return Container(
|
||||
margin: const EdgeInsets.only(top: 1),
|
||||
height: 48,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
Obx(
|
||||
() => ActionItem(
|
||||
icon: const Icon(FontAwesomeIcons.thumbsUp),
|
||||
selectIcon: const Icon(FontAwesomeIcons.solidThumbsUp),
|
||||
onTap: () => handleState(videoIntroController.actionLikeVideo),
|
||||
onLongPress: () =>
|
||||
handleState(videoIntroController.actionOneThree),
|
||||
selectStatus: videoIntroController.hasLike.value,
|
||||
loadingStatus: widget.loadingStatus,
|
||||
semanticsLabel: '分享',
|
||||
semanticsLabel: '点赞',
|
||||
text: !widget.loadingStatus
|
||||
? Utils.numFormat(videoDetail.stat!.share!)
|
||||
: '分享',
|
||||
? Utils.numFormat(videoDetail.stat!.like!)
|
||||
: '-',
|
||||
needAnim: true,
|
||||
hasTriple: videoIntroController.hasLike.value &&
|
||||
videoIntroController.hasCoin &&
|
||||
videoIntroController.hasFav.value,
|
||||
callBack: (start) {
|
||||
if (start) {
|
||||
HapticFeedback.lightImpact();
|
||||
_coinKey.currentState?.controller?.forward();
|
||||
_favKey.currentState?.controller?.forward();
|
||||
} else {
|
||||
_coinKey.currentState?.controller?.reverse();
|
||||
_favKey.currentState?.controller?.reverse();
|
||||
}
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
});
|
||||
),
|
||||
Obx(
|
||||
() => ActionItem(
|
||||
icon: const Icon(FontAwesomeIcons.thumbsDown),
|
||||
selectIcon: const Icon(FontAwesomeIcons.solidThumbsDown),
|
||||
onTap: () => handleState(videoIntroController.actionDislikeVideo),
|
||||
selectStatus: videoIntroController.hasDislike.value,
|
||||
loadingStatus: widget.loadingStatus,
|
||||
semanticsLabel: '点踩',
|
||||
text: "点踩",
|
||||
),
|
||||
),
|
||||
Obx(
|
||||
() => ActionItem(
|
||||
key: _coinKey,
|
||||
icon: const Icon(FontAwesomeIcons.b),
|
||||
selectIcon: const Icon(FontAwesomeIcons.b),
|
||||
onTap: () => handleState(videoIntroController.actionCoinVideo),
|
||||
selectStatus: videoIntroController.hasCoin,
|
||||
loadingStatus: widget.loadingStatus,
|
||||
semanticsLabel: '投币',
|
||||
text: !widget.loadingStatus
|
||||
? Utils.numFormat(videoDetail.stat!.coin!)
|
||||
: '-',
|
||||
needAnim: true,
|
||||
),
|
||||
),
|
||||
Obx(
|
||||
() => ActionItem(
|
||||
key: _favKey,
|
||||
icon: const Icon(FontAwesomeIcons.star),
|
||||
selectIcon: const Icon(FontAwesomeIcons.solidStar),
|
||||
onTap: () => videoIntroController.showFavBottomSheet(context),
|
||||
onLongPress: () => videoIntroController
|
||||
.showFavBottomSheet(context, type: 'longPress'),
|
||||
selectStatus: videoIntroController.hasFav.value,
|
||||
loadingStatus: widget.loadingStatus,
|
||||
semanticsLabel: '收藏',
|
||||
text: !widget.loadingStatus
|
||||
? Utils.numFormat(videoDetail.stat!.favorite!)
|
||||
: '-',
|
||||
needAnim: true,
|
||||
),
|
||||
),
|
||||
Obx(
|
||||
() => ActionItem(
|
||||
icon: const Icon(FontAwesomeIcons.clock),
|
||||
selectIcon: const Icon(FontAwesomeIcons.solidClock),
|
||||
onTap: () => handleState(videoIntroController.viewLater),
|
||||
selectStatus: videoIntroController.hasLater.value,
|
||||
loadingStatus: widget.loadingStatus,
|
||||
semanticsLabel: '再看',
|
||||
text: '再看',
|
||||
),
|
||||
),
|
||||
ActionItem(
|
||||
icon: const Icon(FontAwesomeIcons.shareFromSquare),
|
||||
onTap: () => videoIntroController.actionShareVideo(context),
|
||||
selectStatus: false,
|
||||
loadingStatus: widget.loadingStatus,
|
||||
semanticsLabel: '分享',
|
||||
text: !widget.loadingStatus
|
||||
? Utils.numFormat(videoDetail.stat!.share!)
|
||||
: '分享',
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget actionRow(
|
||||
@@ -1078,14 +1026,12 @@ class _VideoInfoState extends State<VideoInfo> {
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
ActionRowItem(
|
||||
icon: const Icon(FontAwesomeIcons.share),
|
||||
onTap: () => videoIntroController.actionShareVideo(context),
|
||||
selectStatus: false,
|
||||
loadingStatus: widget.loadingStatus,
|
||||
// text: !loadingStatus
|
||||
// ? videoDetail.stat!.share!.toString()
|
||||
// : '-',
|
||||
text: '转发'),
|
||||
icon: const Icon(FontAwesomeIcons.share),
|
||||
onTap: () => videoIntroController.actionShareVideo(context),
|
||||
selectStatus: false,
|
||||
loadingStatus: widget.loadingStatus,
|
||||
text: '转发',
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -1110,7 +1056,6 @@ class _VideoInfoState extends State<VideoInfo> {
|
||||
String matchStr = match[0]!;
|
||||
if (RegExp(r'^av\d+$', caseSensitive: false).hasMatch(matchStr)) {
|
||||
try {
|
||||
// validate
|
||||
int aid = int.parse(matchStr.substring(2));
|
||||
IdUtils.av2bv(aid);
|
||||
spanChildren.add(
|
||||
@@ -1130,7 +1075,6 @@ class _VideoInfoState extends State<VideoInfo> {
|
||||
} else if (RegExp(r'^bv[a-z\d]{10}$', caseSensitive: false)
|
||||
.hasMatch(matchStr)) {
|
||||
try {
|
||||
// validate
|
||||
IdUtils.bv2av(matchStr);
|
||||
spanChildren.add(
|
||||
TextSpan(
|
||||
|
||||
@@ -150,11 +150,9 @@ class ActionItemState extends State<ActionItem>
|
||||
onTapDown: (details) => _isThumbsUp ? _startLongPress() : null,
|
||||
onTapUp: (details) => _isThumbsUp ? _cancelLongPress() : null,
|
||||
onTapCancel: () => _isThumbsUp ? _cancelLongPress(true) : null,
|
||||
// borderRadius: StyleString.mdRadius,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
// const SizedBox(height: 2),
|
||||
Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
@@ -231,7 +229,6 @@ class _ArcPainter extends CustomPainter {
|
||||
);
|
||||
|
||||
const startAngle = -pi / 2;
|
||||
// const sweepAngle = -2 * pi;
|
||||
|
||||
canvas.drawArc(rect, startAngle, sweepAngle, false, paint);
|
||||
}
|
||||
|
||||
@@ -147,7 +147,6 @@ class _FavPanelState extends State<FavPanel> {
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// 骨架屏
|
||||
return const Center(
|
||||
child: CircularProgressIndicator(),
|
||||
);
|
||||
|
||||
@@ -152,7 +152,6 @@ class _GroupPanelState extends State<GroupPanel> {
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// 骨架屏
|
||||
return const Center(
|
||||
child: CircularProgressIndicator(),
|
||||
);
|
||||
|
||||
@@ -67,15 +67,14 @@ class _PagesPanelState extends State<PagesPanel> {
|
||||
if (!_scrollController.hasClients || pages.isEmpty) {
|
||||
return;
|
||||
}
|
||||
const double itemWidth = 150; // 每个列表项的宽度
|
||||
const double itemWidth = 150;
|
||||
final double targetOffset = (pageIndex * itemWidth - itemWidth / 2).clamp(
|
||||
_scrollController.position.minScrollExtent,
|
||||
_scrollController.position.maxScrollExtent);
|
||||
// 滑动至目标位置
|
||||
_scrollController.animateTo(
|
||||
targetOffset,
|
||||
duration: const Duration(milliseconds: 300), // 滑动动画持续时间
|
||||
curve: Curves.easeInOut, // 滑动动画曲线
|
||||
duration: const Duration(milliseconds: 300),
|
||||
curve: Curves.easeInOut,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -61,9 +61,6 @@ class _SeasonPanelState extends State<SeasonPanel> {
|
||||
}
|
||||
|
||||
/// 取对应 season_id 的 episodes
|
||||
// episodes = widget.ugcSeason.sections!
|
||||
// .firstWhere((e) => e.seasonId == widget.ugcSeason.id)
|
||||
// .episodes;
|
||||
currentIndex.value = episodes.indexWhere(
|
||||
(EpisodeItem e) => e.cid == _videoDetailController.seasonCid);
|
||||
_listener = _videoDetailController.cid.listen((int cid) {
|
||||
@@ -86,17 +83,6 @@ class _SeasonPanelState extends State<SeasonPanel> {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
// void changeFucCall(item, int i) async {
|
||||
// await widget.changeFuc!(
|
||||
// IdUtils.av2bv(item.aid),
|
||||
// item.cid,
|
||||
// item.aid,
|
||||
// );
|
||||
// currentIndex = i;
|
||||
// Get.back();
|
||||
// setState(() {});
|
||||
// }
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (episodes.isEmpty) {
|
||||
|
||||
@@ -50,7 +50,6 @@ class _VideoReplyPanelState extends State<VideoReplyPanel>
|
||||
|
||||
String get heroTag => widget.heroTag;
|
||||
|
||||
// 添加页面缓存
|
||||
@override
|
||||
bool get wantKeepAlive => true;
|
||||
|
||||
|
||||
@@ -65,19 +65,12 @@ class ReplyItemGrpc extends StatelessWidget {
|
||||
return Material(
|
||||
color: Colors.transparent,
|
||||
child: InkWell(
|
||||
// 点击整个评论区 评论详情/回复
|
||||
onTap: () {
|
||||
feedBack();
|
||||
replyReply?.call(replyItem, null);
|
||||
},
|
||||
onLongPress: () {
|
||||
feedBack();
|
||||
// showDialog(
|
||||
// context: context,
|
||||
// builder: (context) => AlertDialog(
|
||||
// content: SelectableText(jsonEncode(replyItem.toProto3Json())),
|
||||
// ),
|
||||
// );
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
useSafeArea: true,
|
||||
@@ -118,17 +111,6 @@ class ReplyItemGrpc extends StatelessWidget {
|
||||
Positioned(
|
||||
top: 8,
|
||||
right: 12,
|
||||
// child: GestureDetector(
|
||||
// onTap: replyItem.member.garbCardJumpUrl.isNotEmpty
|
||||
// ? () {
|
||||
// Get.toNamed(
|
||||
// 'webview',
|
||||
// parameters: {
|
||||
// 'url': replyItem.member.garbCardJumpUrl
|
||||
// },
|
||||
// );
|
||||
// }
|
||||
// : null,
|
||||
child: Stack(
|
||||
alignment: Alignment.centerRight,
|
||||
children: [
|
||||
@@ -155,7 +137,6 @@ class ReplyItemGrpc extends StatelessWidget {
|
||||
],
|
||||
),
|
||||
),
|
||||
// ),
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
child: _buildAuthorPanel(context),
|
||||
@@ -214,7 +195,6 @@ class ReplyItemGrpc extends StatelessWidget {
|
||||
bottom: 0,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
//borderRadius: BorderRadius.circular(7),
|
||||
shape: BoxShape.circle,
|
||||
color: Theme.of(context).colorScheme.surface,
|
||||
),
|
||||
@@ -225,14 +205,12 @@ class ReplyItemGrpc extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
),
|
||||
//https://www.bilibili.com/blackboard/activity-whPrHsYJ2.html
|
||||
if (replyItem.member.officialVerifyType == 0)
|
||||
Positioned(
|
||||
left: 0,
|
||||
bottom: 0,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
// borderRadius: BorderRadius.circular(8),
|
||||
shape: BoxShape.circle,
|
||||
color: Theme.of(context).colorScheme.surface,
|
||||
),
|
||||
@@ -250,7 +228,6 @@ class ReplyItemGrpc extends StatelessWidget {
|
||||
bottom: 0,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
// borderRadius: BorderRadius.circular(8),
|
||||
shape: BoxShape.circle,
|
||||
color: Theme.of(context).colorScheme.surface,
|
||||
),
|
||||
@@ -270,8 +247,7 @@ class ReplyItemGrpc extends StatelessWidget {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
/// fix Stack内GestureDetector onTap无效
|
||||
children: [
|
||||
GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onTap: () {
|
||||
@@ -281,7 +257,7 @@ class ReplyItemGrpc extends StatelessWidget {
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
children: [
|
||||
lfAvtar(context),
|
||||
const SizedBox(width: 12),
|
||||
Column(
|
||||
@@ -415,9 +391,8 @@ class ReplyItemGrpc extends StatelessWidget {
|
||||
if (replyLevel != '') buttonAction(context, replyItem.replyControl),
|
||||
// 一楼的评论
|
||||
if (replyLevel == '1' &&
|
||||
( //replyItem.replyControl!.isShow! ||
|
||||
replyItem.replies.isNotEmpty ||
|
||||
replyItem.replyControl.subReplyEntryText.isNotEmpty)) ...[
|
||||
(replyItem.replies.isNotEmpty ||
|
||||
replyItem.replyControl.subReplyEntryText.isNotEmpty)) ...[
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 5, bottom: 12),
|
||||
child: replyItemRow(
|
||||
@@ -699,21 +674,14 @@ class ReplyItemGrpc extends StatelessWidget {
|
||||
final textSize = textPainter.size;
|
||||
final double maxHeight = textPainter.preferredLineHeight * 6;
|
||||
var position = textPainter.getPositionForOffset(
|
||||
Offset(
|
||||
textSize.width,
|
||||
maxHeight, // textSize.height,
|
||||
),
|
||||
Offset(textSize.width, maxHeight),
|
||||
);
|
||||
// final endOffset = textPainter.getOffsetBefore(position.offset);
|
||||
message = message.substring(0, position.offset);
|
||||
}
|
||||
|
||||
// return TextSpan(text: message);
|
||||
|
||||
// 投票
|
||||
if (content.hasVote()) {
|
||||
message.splitMapJoin(RegExp(r"\{vote:\d+?\}"), onMatch: (Match match) {
|
||||
// String matchStr = match[0]!;
|
||||
spanChildren.add(
|
||||
TextSpan(
|
||||
text: '投票: ${content.vote.title}',
|
||||
@@ -739,12 +707,6 @@ class ReplyItemGrpc extends StatelessWidget {
|
||||
message = message.replaceAll(RegExp(r"\{vote:\d+?\}"), "");
|
||||
}
|
||||
message = parse(message).body?.text ?? message;
|
||||
// .replaceAll('&', '&')
|
||||
// .replaceAll('<', '<')
|
||||
// .replaceAll('>', '>')
|
||||
// .replaceAll('"', '"')
|
||||
// .replaceAll(''', "'")
|
||||
// .replaceAll(' ', ' ');
|
||||
// 构建正则表达式
|
||||
final List<String> specialTokens = [
|
||||
...content.emote.keys,
|
||||
@@ -770,12 +732,6 @@ class ReplyItemGrpc extends StatelessWidget {
|
||||
spanChildren.add(TextSpan(
|
||||
text: str,
|
||||
));
|
||||
// TextSpan(
|
||||
//
|
||||
// text: str,
|
||||
// recognizer: TapGestureRecognizer()
|
||||
// ..onTap = () => replyReply
|
||||
// ?.call(replyItem.root == 0 ? replyItem : fReplyItem)))));
|
||||
}
|
||||
|
||||
late final bool enableWordRe =
|
||||
@@ -883,7 +839,7 @@ class ReplyItemGrpc extends StatelessWidget {
|
||||
if (content.url[matchStr]?.hasPrefixIcon() == true) ...[
|
||||
WidgetSpan(
|
||||
child: Image.network(
|
||||
content.url[matchStr]!.prefixIcon.http2https,
|
||||
Utils.thumbnailImgUrl(content.url[matchStr]!.prefixIcon),
|
||||
height: 19,
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
),
|
||||
@@ -998,7 +954,7 @@ class ReplyItemGrpc extends StatelessWidget {
|
||||
if (content.url[patternStr]?.hasPrefixIcon() == true) ...[
|
||||
WidgetSpan(
|
||||
child: Image.network(
|
||||
content.url[patternStr]!.prefixIcon.http2https,
|
||||
Utils.thumbnailImgUrl(content.url[patternStr]!.prefixIcon),
|
||||
height: 19,
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
),
|
||||
@@ -1084,7 +1040,6 @@ class ReplyItemGrpc extends StatelessWidget {
|
||||
),
|
||||
);
|
||||
}
|
||||
// spanChildren.add(TextSpan(text: matchMember));
|
||||
return TextSpan(children: spanChildren);
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@ class ZanButtonGrpc extends StatefulWidget {
|
||||
class _ZanButtonGrpcState extends State<ZanButtonGrpc> {
|
||||
Future onHateReply() async {
|
||||
feedBack();
|
||||
// SmartDialog.showLoading(msg: 'piliplus ...');
|
||||
final int oid = widget.replyItem.oid.toInt();
|
||||
final int rpid = widget.replyItem.id.toInt();
|
||||
// 1 已点赞 2 不喜欢 0 未操作
|
||||
@@ -46,7 +45,6 @@ class _ZanButtonGrpcState extends State<ZanButtonGrpc> {
|
||||
}
|
||||
widget.replyItem.replyControl.action = $fixnum.Int64(2);
|
||||
} else {
|
||||
// replyItem.like = replyItem.like! - 1;
|
||||
widget.replyItem.replyControl.action = $fixnum.Int64(0);
|
||||
}
|
||||
setState(() {});
|
||||
@@ -58,7 +56,6 @@ class _ZanButtonGrpcState extends State<ZanButtonGrpc> {
|
||||
// 评论点赞
|
||||
Future onLikeReply() async {
|
||||
feedBack();
|
||||
// SmartDialog.showLoading(msg: 'piliplus ...');
|
||||
final int oid = widget.replyItem.oid.toInt();
|
||||
final int rpid = widget.replyItem.id.toInt();
|
||||
// 1 已点赞 2 不喜欢 0 未操作
|
||||
@@ -70,7 +67,6 @@ class _ZanButtonGrpcState extends State<ZanButtonGrpc> {
|
||||
rpid: rpid,
|
||||
action: action,
|
||||
);
|
||||
// SmartDialog.dismiss();
|
||||
if (res['status']) {
|
||||
SmartDialog.showToast(
|
||||
widget.replyItem.replyControl.action.toInt() != 1 ? '点赞成功' : '取消赞');
|
||||
|
||||
@@ -70,14 +70,11 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
late VideoDetailController videoDetailController;
|
||||
late VideoReplyController _videoReplyController;
|
||||
PlPlayerController? plPlayerController;
|
||||
late StreamController<double> appbarStream;
|
||||
late VideoIntroController videoIntroController;
|
||||
late BangumiIntroController bangumiIntroController;
|
||||
late final _introController = ScrollController();
|
||||
late String heroTag;
|
||||
|
||||
double doubleOffset = 0;
|
||||
|
||||
// 自动退出全屏
|
||||
late bool autoExitFullscreen;
|
||||
late bool autoPlayEnable;
|
||||
@@ -86,12 +83,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
late bool autoPiP;
|
||||
late bool pipNoDanmaku;
|
||||
late bool removeSafeArea;
|
||||
// late bool showStatusBarBackgroundColor;
|
||||
// final Floating floating = Floating();
|
||||
// 生命周期监听
|
||||
// late final AppLifecycleListener _lifecycleListener;
|
||||
bool isShowing = true;
|
||||
// StreamSubscription<Duration>? _bufferedListener;
|
||||
bool get isFullScreen => plPlayerController?.isFullScreen.value ?? false;
|
||||
|
||||
bool get _shouldShowSeasonPanel =>
|
||||
@@ -169,13 +161,8 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
setting.get(SettingBoxKey.enableVerticalExpand, defaultValue: false);
|
||||
removeSafeArea = setting.get(SettingBoxKey.videoPlayerRemoveSafeArea,
|
||||
defaultValue: false);
|
||||
// showStatusBarBackgroundColor = setting.get(
|
||||
// SettingBoxKey.videoPlayerShowStatusBarBackgroundColor,
|
||||
// defaultValue: false);
|
||||
if (removeSafeArea) hideStatusBar();
|
||||
videoSourceInit();
|
||||
appbarStreamListen();
|
||||
// lifecycleListener();
|
||||
autoScreen();
|
||||
if (Platform.isAndroid) {
|
||||
Utils.channel.setMethodCallHandler((call) async {
|
||||
@@ -236,11 +223,6 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
plPlayerController?.play();
|
||||
}
|
||||
|
||||
// 流
|
||||
appbarStreamListen() {
|
||||
appbarStream = StreamController<double>();
|
||||
}
|
||||
|
||||
// 播放器状态监听
|
||||
void playerListener(PlayerStatus? status) async {
|
||||
try {
|
||||
@@ -348,27 +330,6 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
await plPlayerController!.autoEnterFullscreen();
|
||||
}
|
||||
|
||||
// // 生命周期监听
|
||||
// void lifecycleListener() {
|
||||
// _lifecycleListener = AppLifecycleListener(
|
||||
// onResume: () => _handleTransition('resume'),
|
||||
// // 后台
|
||||
// onInactive: () => _handleTransition('inactive'),
|
||||
// // 在Android和iOS端不生效
|
||||
// onHide: () => _handleTransition('hide'),
|
||||
// onShow: () => _handleTransition('show'),
|
||||
// onPause: () => _handleTransition('pause'),
|
||||
// onRestart: () => _handleTransition('restart'),
|
||||
// onDetach: () => _handleTransition('detach'),
|
||||
// // 只作用于桌面端
|
||||
// onExitRequested: () {
|
||||
// ScaffoldMessenger.maybeOf(context)
|
||||
// ?.showSnackBar(const SnackBar(content: Text("拦截应用退出")));
|
||||
// return Future.value(AppExitResponse.cancel);
|
||||
// },
|
||||
// );
|
||||
// }
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_listenerDetail?.cancel();
|
||||
@@ -396,16 +357,12 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
}
|
||||
videoDetailController.positionSubscription?.cancel();
|
||||
videoIntroController.canelTimer();
|
||||
appbarStream.close();
|
||||
// floating.dispose();
|
||||
// videoDetailController.floating?.dispose();
|
||||
videoIntroController.videoDetail.close();
|
||||
videoDetailController.cid.close();
|
||||
if (!horizontalScreen) {
|
||||
AutoOrientation.portraitUpMode();
|
||||
}
|
||||
shutdownTimerService.handleWaitingFinished();
|
||||
// _bufferedListener?.cancel();
|
||||
if (videoDetailController.plPlayerController.backToHome != true) {
|
||||
videoPlayerServiceHandler.onVideoDetailDispose(heroTag);
|
||||
}
|
||||
@@ -418,16 +375,13 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
PlPlayerController.updatePlayCount();
|
||||
}
|
||||
VideoDetailPageV.routeObserver.unsubscribe(this);
|
||||
// _lifecycleListener.dispose();
|
||||
showStatusBar();
|
||||
// _animationController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
// 离开当前页面时
|
||||
void didPushNext() async {
|
||||
// _bufferedListener?.cancel();
|
||||
if (videoDetailController.imageStatus) {
|
||||
return;
|
||||
}
|
||||
@@ -442,11 +396,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
videoDetailController.playerStatus =
|
||||
plPlayerController?.playerStatus.status.value;
|
||||
|
||||
/// 开启
|
||||
// if (setting.get(SettingBoxKey.enableAutoBrightness, defaultValue: true)
|
||||
// as bool) {
|
||||
videoDetailController.brightness = plPlayerController?.brightness.value;
|
||||
// }
|
||||
if (plPlayerController != null) {
|
||||
videoDetailController.makeHeartBeat();
|
||||
videoDetailController.showVP = plPlayerController!.showVP.value;
|
||||
@@ -491,7 +441,6 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
}
|
||||
}
|
||||
super.didPopNext();
|
||||
// final bool autoplay = autoPlayEnable;
|
||||
videoDetailController.autoPlay.value =
|
||||
!videoDetailController.isShowCover.value;
|
||||
if (videoDetailController.isShowCover.value.not) {
|
||||
@@ -504,29 +453,6 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
await videoDetailController.playerInit();
|
||||
}
|
||||
|
||||
// if (videoDetailController.playerStatus == PlayerStatus.playing) {
|
||||
// plPlayerController?.play();
|
||||
// }
|
||||
|
||||
/// 未开启自动播放时,未播放跳转下一页返回/播放后跳转下一页返回
|
||||
// if (autoplay) {
|
||||
// // await Future.delayed(const Duration(milliseconds: 300));
|
||||
// debugPrint(plPlayerController);
|
||||
// if (plPlayerController?.buffered.value == Duration.zero) {
|
||||
// _bufferedListener = plPlayerController?.buffered.listen((p0) {
|
||||
// debugPrint("p0");
|
||||
// debugPrint(p0);
|
||||
// if (p0 > Duration.zero) {
|
||||
// _bufferedListener!.cancel();
|
||||
// plPlayerController?.seekTo(videoDetailController.defaultST);
|
||||
// plPlayerController?.play();
|
||||
// }
|
||||
// });
|
||||
// } else {
|
||||
// plPlayerController?.seekTo(videoDetailController.defaultST);
|
||||
// plPlayerController?.play();
|
||||
// }
|
||||
// }
|
||||
Future.delayed(const Duration(milliseconds: 600), () {
|
||||
AutoOrientation.fullAutoMode();
|
||||
});
|
||||
@@ -544,17 +470,6 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
: Theme.of(context);
|
||||
}
|
||||
|
||||
// void _handleTransition(String name) {
|
||||
// switch (name) {
|
||||
// case 'inactive':
|
||||
// if (plPlayerController != null &&
|
||||
// playerStatus == PlayerStatus.playing) {
|
||||
// autoEnterPip();
|
||||
// }
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
void enterPip() {
|
||||
if (Get.currentRoute.startsWith('/video') &&
|
||||
videoDetailController.floating != null) {
|
||||
@@ -624,8 +539,8 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
bottom: !removeSafeArea &&
|
||||
MediaQuery.of(context).orientation == Orientation.portrait &&
|
||||
isFullScreen,
|
||||
left: false, //!isFullScreen,
|
||||
right: false, //!isFullScreen,
|
||||
left: false,
|
||||
right: false,
|
||||
child: Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
key: videoDetailController.scaffoldKey,
|
||||
@@ -1181,41 +1096,6 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
),
|
||||
),
|
||||
),
|
||||
// Expanded(
|
||||
// child: TabBarView(
|
||||
// physics: const ClampingScrollPhysics(),
|
||||
// controller: videoDetailController.tabCtr,
|
||||
// children: [
|
||||
// CustomScrollView(
|
||||
// key: const PageStorageKey<String>('简介'),
|
||||
// slivers: [
|
||||
// if (videoDetailController.videoType ==
|
||||
// SearchType.video) ...[
|
||||
// const VideoIntroPanel(),
|
||||
// ] else if (videoDetailController.videoType ==
|
||||
// SearchType.media_bangumi) ...[
|
||||
// Obx(() => BangumiIntroPanel(
|
||||
// cid: videoDetailController.cid.value)),
|
||||
// ],
|
||||
// SliverToBoxAdapter(
|
||||
// child: Divider(
|
||||
// indent: 12,
|
||||
// endIndent: 12,
|
||||
// color: themeData.dividerColor.withOpacity(0.06),
|
||||
// ),
|
||||
// ),
|
||||
// const RelatedVideoPanel(),
|
||||
// ],
|
||||
// ),
|
||||
// Obx(
|
||||
// () => VideoReplyPanel(
|
||||
// bvid: videoDetailController.bvid,
|
||||
// oid: videoDetailController.oid.value,
|
||||
// ),
|
||||
// )
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
],
|
||||
);
|
||||
}
|
||||
@@ -1319,7 +1199,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
left: !removeSafeArea && !isFullScreen,
|
||||
right: !removeSafeArea && !isFullScreen,
|
||||
top: !removeSafeArea,
|
||||
bottom: false, //!removeSafeArea,
|
||||
bottom: false,
|
||||
child: childWhenDisabledLandscapeInner,
|
||||
),
|
||||
),
|
||||
@@ -1339,7 +1219,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
left: !removeSafeArea && !isFullScreen,
|
||||
right: !removeSafeArea && !isFullScreen,
|
||||
top: !removeSafeArea,
|
||||
bottom: false, //!removeSafeArea,
|
||||
bottom: false,
|
||||
child: childWhenDisabledAlmostSquareInner,
|
||||
),
|
||||
);
|
||||
@@ -1580,53 +1460,14 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
|
||||
return LayoutBuilder(
|
||||
builder: (BuildContext context, BoxConstraints constraints) {
|
||||
// if (!isShowing) {
|
||||
// return ColoredBox(color: themeData.colorScheme.surface);
|
||||
// }
|
||||
if (constraints.maxWidth > constraints.maxHeight * 1.25) {
|
||||
// hideStatusBar();
|
||||
// videoDetailController.hiddenReplyReplyPanel();
|
||||
return autoChoose(childWhenDisabledLandscape);
|
||||
} else if (constraints.maxWidth * (9 / 16) <
|
||||
(2 / 5) * constraints.maxHeight) {
|
||||
// if (!isFullScreen) {
|
||||
// if (!removeSafeArea) showStatusBar();
|
||||
// }
|
||||
return autoChoose(childWhenDisabled);
|
||||
} else {
|
||||
// if (!isFullScreen) {
|
||||
// if (!removeSafeArea) showStatusBar();
|
||||
// }
|
||||
return autoChoose(childWhenDisabledAlmostSquare);
|
||||
}
|
||||
//
|
||||
// final Orientation orientation =
|
||||
// constraints.maxWidth > constraints.maxHeight * 1.25
|
||||
// ? Orientation.landscape
|
||||
// : Orientation.portrait;
|
||||
// if (orientation == Orientation.landscape) {
|
||||
// if (!horizontalScreen) {
|
||||
// hideStatusBar();
|
||||
// videoDetailController.hiddenReplyReplyPanel();
|
||||
// }
|
||||
// } else {
|
||||
// if (!isFullScreen) {
|
||||
// showStatusBar();
|
||||
// }
|
||||
// }
|
||||
// if (Platform.isAndroid) {
|
||||
// return PiPSwitcher(
|
||||
// childWhenDisabled:
|
||||
// !horizontalScreen || orientation == Orientation.portrait
|
||||
// ? childWhenDisabled
|
||||
// : childWhenDisabledLandscape,
|
||||
// childWhenEnabled: childWhenEnabled,
|
||||
// floating: floating,
|
||||
// );
|
||||
// }
|
||||
// return !horizontalScreen || orientation == Orientation.portrait
|
||||
// ? childWhenDisabled
|
||||
// : childWhenDisabledLandscape;
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -1671,8 +1512,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
labelStyle:
|
||||
TabBarTheme.of(context).labelStyle?.copyWith(fontSize: 13) ??
|
||||
const TextStyle(fontSize: 13),
|
||||
labelPadding:
|
||||
const EdgeInsets.symmetric(horizontal: 10.0), // 设置每个标签的宽度
|
||||
labelPadding: const EdgeInsets.symmetric(horizontal: 10.0),
|
||||
dividerColor: Colors.transparent,
|
||||
dividerHeight: 0,
|
||||
onTap: (value) {
|
||||
@@ -2094,8 +1934,6 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
bvid: videoDetailController.bvid,
|
||||
aid: IdUtils.bv2av(videoDetailController.bvid),
|
||||
cid: videoDetailController.cid.value,
|
||||
// count: videoIntroController.videoDetail.value.pages!.length,
|
||||
// name: videoIntroController.videoDetail.value.pages!,
|
||||
isReversed:
|
||||
videoIntroController.videoDetail.value.isPageReversed,
|
||||
changeFucCall: videoDetailController.videoType ==
|
||||
@@ -2146,10 +1984,6 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
videoIntroController.videoDetail.value.ugcSeason!.id,
|
||||
list: videoIntroController
|
||||
.videoDetail.value.ugcSeason!.sections!,
|
||||
// count: videoIntroController
|
||||
// .videoDetail.value.ugcSeason!.epCount!,
|
||||
// name:
|
||||
// videoIntroController.videoDetail.value.ugcSeason!.title!,
|
||||
bvid: videoDetailController.bvid,
|
||||
aid: IdUtils.bv2av(videoDetailController.bvid),
|
||||
cid: videoDetailController.seasonCid ?? 0,
|
||||
|
||||
@@ -45,11 +45,9 @@ class _AiDetailState extends CommonCollapseSlidePageState<AiDetail> {
|
||||
spanChildren.add(
|
||||
TextSpan(
|
||||
text: match.group(0),
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.primary), // 设置颜色为蓝色
|
||||
style: TextStyle(color: Theme.of(context).colorScheme.primary),
|
||||
recognizer: TapGestureRecognizer()
|
||||
..onTap = () {
|
||||
// 处理点击事件
|
||||
try {
|
||||
PageUtils.handleWebview(match.group(0)!);
|
||||
} catch (err) {
|
||||
|
||||
@@ -50,15 +50,6 @@ class ScrollAppBar extends StatelessWidget {
|
||||
],
|
||||
),
|
||||
),
|
||||
// actions: [
|
||||
// IconButton(
|
||||
// onPressed: () {},
|
||||
// icon: const Icon(
|
||||
// Icons.share,
|
||||
// size: 20,
|
||||
// )),
|
||||
// const SizedBox(width: 12)
|
||||
// ],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class ExpandedSection extends StatefulWidget {
|
||||
final Widget? child;
|
||||
final bool expand;
|
||||
final double begin;
|
||||
final double end;
|
||||
|
||||
const ExpandedSection({
|
||||
super.key,
|
||||
this.expand = false,
|
||||
this.child,
|
||||
this.begin = 0.0,
|
||||
this.end = 1.0,
|
||||
});
|
||||
|
||||
@override
|
||||
State<ExpandedSection> createState() => _ExpandedSectionState();
|
||||
}
|
||||
|
||||
class _ExpandedSectionState extends State<ExpandedSection>
|
||||
with SingleTickerProviderStateMixin {
|
||||
late AnimationController expandController;
|
||||
late Animation<double> animation;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
prepareAnimations();
|
||||
_runExpandCheck();
|
||||
}
|
||||
|
||||
void prepareAnimations() {
|
||||
expandController = AnimationController(
|
||||
vsync: this, duration: const Duration(milliseconds: 400));
|
||||
Animation<double> curve = CurvedAnimation(
|
||||
parent: expandController,
|
||||
curve: Curves.fastOutSlowIn,
|
||||
);
|
||||
animation = Tween(begin: widget.begin, end: widget.end).animate(curve);
|
||||
// animation = CurvedAnimation(
|
||||
// parent: expandController,
|
||||
// curve: Curves.fastOutSlowIn,
|
||||
// );
|
||||
}
|
||||
|
||||
void _runExpandCheck() {
|
||||
if (widget.expand) {
|
||||
expandController.forward();
|
||||
} else {
|
||||
expandController.reverse();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void didUpdateWidget(ExpandedSection oldWidget) {
|
||||
super.didUpdateWidget(oldWidget);
|
||||
_runExpandCheck();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
expandController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SizeTransition(
|
||||
axisAlignment: -1.0,
|
||||
sizeFactor: animation,
|
||||
child: widget.child,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -131,31 +131,6 @@ class HeaderControlState extends State<HeaderControl> {
|
||||
padding: EdgeInsets.zero,
|
||||
children: [
|
||||
const SizedBox(height: 14),
|
||||
// ListTile(
|
||||
// onTap: () {},
|
||||
// dense: true,
|
||||
// enabled: false,
|
||||
// leading:
|
||||
// const Icon(Icons.network_cell_outlined, size: 20),
|
||||
// title: Text('省流模式', style: titleStyle),
|
||||
// subtitle: Text('低画质 | 减少视频缓存', style: subTitleStyle),
|
||||
// trailing: Transform.scale(
|
||||
// scale: 0.75,
|
||||
// child: Switch(
|
||||
// thumbIcon: WidgetStateProperty.resolveWith<Icon?>(
|
||||
// (Set<WidgetState> states) {
|
||||
// if (states.isNotEmpty &&
|
||||
// states.first == WidgetState.selected) {
|
||||
// return const Icon(Icons.done);
|
||||
// }
|
||||
// return null; // All other states will use the default thumbIcon.
|
||||
// }),
|
||||
// value: false,
|
||||
// onChanged: (value) => {},
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// if (videoDetailCtr.userInfo != null)
|
||||
ListTile(
|
||||
dense: true,
|
||||
onTap: () {
|
||||
@@ -364,7 +339,6 @@ class HeaderControlState extends State<HeaderControl> {
|
||||
};
|
||||
},
|
||||
),
|
||||
|
||||
ListTile(
|
||||
dense: true,
|
||||
onTap: () => {Get.back(), showSetVideoQa()},
|
||||
@@ -1253,7 +1227,6 @@ class HeaderControlState extends State<HeaderControl> {
|
||||
min: 0,
|
||||
max: 1,
|
||||
value: subtitleBgOpaticy,
|
||||
// label: '${(subtitleBgOpaticy * 100).toInt()}%',
|
||||
onChanged: (double val) {
|
||||
updateOpacity(val.toPrecision(2));
|
||||
},
|
||||
@@ -1291,13 +1264,6 @@ class HeaderControlState extends State<HeaderControl> {
|
||||
{'value': 6, 'label': '彩色'},
|
||||
];
|
||||
final List blockTypes = widget.controller.blockTypes;
|
||||
// 显示区域
|
||||
// final List<Map<String, dynamic>> showAreas = [
|
||||
// {'value': 0.25, 'label': '1/4屏'},
|
||||
// {'value': 0.5, 'label': '半屏'},
|
||||
// {'value': 0.75, 'label': '3/4屏'},
|
||||
// {'value': 1.0, 'label': '满屏'},
|
||||
// ];
|
||||
// 智能云屏蔽
|
||||
int danmakuWeight = widget.controller.danmakuWeight;
|
||||
// 显示区域
|
||||
@@ -1814,7 +1780,6 @@ class HeaderControlState extends State<HeaderControl> {
|
||||
min: 1.0,
|
||||
max: 3.0,
|
||||
value: danmakuLineHeight,
|
||||
// label: '$danmakuLineHeight',
|
||||
onChanged: (double val) {
|
||||
updateLineHeight(val.toPrecision(1));
|
||||
},
|
||||
@@ -2052,14 +2017,6 @@ class HeaderControlState extends State<HeaderControl> {
|
||||
return SizedBox.shrink();
|
||||
},
|
||||
),
|
||||
// ComBtn(
|
||||
// icon: const Icon(
|
||||
// FontAwesomeIcons.cropSimple,
|
||||
// size: 15,
|
||||
// color: Colors.white,
|
||||
// ),
|
||||
// fuc: () => _.screenshot(),
|
||||
// ),
|
||||
if (videoDetailCtr.enableSponsorBlock == true)
|
||||
SizedBox(
|
||||
width: 42,
|
||||
@@ -2139,9 +2096,6 @@ class HeaderControlState extends State<HeaderControl> {
|
||||
!plPlayerController.isOpenDanmu.value;
|
||||
setting.put(SettingBoxKey.enableShowDanmaku,
|
||||
plPlayerController.isOpenDanmu.value);
|
||||
// SmartDialog.showToast(
|
||||
// "已${plPlayerController.isOpenDanmu.value ? '开启' : '关闭'}弹幕",
|
||||
// displayTime: const Duration(seconds: 1));
|
||||
},
|
||||
icon: Icon(
|
||||
plPlayerController.isOpenDanmu.value
|
||||
@@ -2171,9 +2125,6 @@ class HeaderControlState extends State<HeaderControl> {
|
||||
SettingBoxKey.enableBackgroundPlay,
|
||||
defaultValue: true);
|
||||
if (!enableBackgroundPlay && mounted) {
|
||||
// SmartDialog.showToast('建议开启【后台播放】功能\n避免画中画没有暂停按钮');
|
||||
// await Future.delayed(const Duration(seconds: 2), () {
|
||||
// });
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Column(
|
||||
@@ -2211,7 +2162,6 @@ class HeaderControlState extends State<HeaderControl> {
|
||||
plPlayerController
|
||||
.setBackgroundPlay(true);
|
||||
SmartDialog.showToast("请重新载入本页面刷新");
|
||||
// Get.back();
|
||||
},
|
||||
child: const Text('启用后台音频服务')),
|
||||
const SizedBox(width: 10),
|
||||
@@ -2510,9 +2460,6 @@ class HeaderControlState extends State<HeaderControl> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// final bool isLandscape =
|
||||
// MediaQuery.of(context).orientation == Orientation.landscape;
|
||||
|
||||
return plPlayerController.showFSActionItem
|
||||
? Obx(() => _buildHeader(true))
|
||||
: _buildHeader(false);
|
||||
|
||||
@@ -6,9 +6,6 @@ import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
import 'package:webdav_client/webdav_client.dart' as webdav;
|
||||
|
||||
class WebDav {
|
||||
late String _webDavUri;
|
||||
late String _webDavUsername;
|
||||
late String _webDavPassword;
|
||||
late String _webdavDirectory;
|
||||
|
||||
webdav.Client? _client;
|
||||
@@ -18,9 +15,9 @@ class WebDav {
|
||||
factory WebDav() => _instance;
|
||||
|
||||
Future<Pair<bool, String?>> init() async {
|
||||
_webDavUri = GStorage.webdavUri;
|
||||
_webDavUsername = GStorage.webdavUsername;
|
||||
_webDavPassword = GStorage.webdavPassword;
|
||||
final webDavUri = GStorage.webdavUri;
|
||||
final webDavUsername = GStorage.webdavUsername;
|
||||
final webDavPassword = GStorage.webdavPassword;
|
||||
_webdavDirectory = GStorage.webdavDirectory;
|
||||
if (_webdavDirectory.endsWith('/').not) {
|
||||
_webdavDirectory += '/';
|
||||
@@ -30,9 +27,9 @@ class WebDav {
|
||||
try {
|
||||
_client = null;
|
||||
final client = webdav.newClient(
|
||||
_webDavUri,
|
||||
user: _webDavUsername,
|
||||
password: _webDavPassword,
|
||||
webDavUri,
|
||||
user: webDavUsername,
|
||||
password: webDavPassword,
|
||||
)
|
||||
..setHeaders({'accept-charset': 'utf-8'})
|
||||
..setConnectTimeout(4000)
|
||||
|
||||
@@ -160,14 +160,6 @@ class _WhisperDetailPageState
|
||||
style: TextStyle(fontSize: 14),
|
||||
),
|
||||
),
|
||||
// ListTile(
|
||||
// onTap: () {
|
||||
// Get.back();
|
||||
// },
|
||||
// dense: true,
|
||||
// title: const Text('删除',
|
||||
// style: TextStyle(fontSize: 14)),
|
||||
// ),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
@@ -397,10 +397,9 @@ class ChatItem extends StatelessWidget {
|
||||
onTap: () async {
|
||||
Get.toNamed('/htmlRender', parameters: {
|
||||
'url': "https://www.bilibili.com/read/cv${content['rid']}/",
|
||||
// 'url': url.startsWith('//') ? url.split('//').last : url,
|
||||
'title': content['title'] ?? "",
|
||||
'id': "cv${content['rid']}",
|
||||
'dynamicType': "read" //content['template_id'] ?? "",
|
||||
'dynamicType': "read"
|
||||
});
|
||||
},
|
||||
child: Column(
|
||||
|
||||
Reference in New Issue
Block a user