chore: clean up

opt: pages

Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
bggRGjQaUbCoE
2025-04-19 18:05:02 +08:00
parent e5f3c3c922
commit a2ef4e6f84
99 changed files with 697 additions and 2097 deletions

View File

@@ -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";
}
}

View File

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

View File

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

View File

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

View File

@@ -70,7 +70,6 @@ class _DanmakuBlockPageState extends State<DanmakuBlockPage> {
TextField(
controller: textController,
autofocus: true,
//decoration: InputDecoration(hintText: hintText),
)
]),
actions: <Widget>[

View File

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

View File

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

View File

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

View File

@@ -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':

View File

@@ -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(
'稍后再看',

View File

@@ -66,7 +66,6 @@ Widget content(bool isSave, BuildContext context, item, source, callback) {
item.modules.moduleDynamic.major.opus.pics.isNotEmpty)
Text.rich(
picsNodes(),
// semanticsLabel: '动态图片',
),
],
),

View File

@@ -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' &&
[

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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']!;

View File

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

View File

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

View File

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

View File

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

View File

@@ -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: [

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -65,7 +65,6 @@ class LiveRoomChat extends StatelessWidget {
);
} catch (err) {
debugPrint(err.toString());
// SmartDialog.showToast(err.toString());
}
},
),

View File

@@ -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('登录成功');

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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: '哔哩哔哩认证',

View File

@@ -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,
// ),
// ),
// ),
// ),
],
),
),

View File

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

View File

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

View File

@@ -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: () => {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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';

View File

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

View File

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

View File

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

View File

@@ -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'];
}

View File

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

View File

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

View File

@@ -147,7 +147,6 @@ class _FavPanelState extends State<FavPanel> {
);
}
} else {
// 骨架屏
return const Center(
child: CircularProgressIndicator(),
);

View File

@@ -152,7 +152,6 @@ class _GroupPanelState extends State<GroupPanel> {
);
}
} else {
// 骨架屏
return const Center(
child: CircularProgressIndicator(),
);

View File

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

View File

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

View File

@@ -50,7 +50,6 @@ class _VideoReplyPanelState extends State<VideoReplyPanel>
String get heroTag => widget.heroTag;
// 添加页面缓存
@override
bool get wantKeepAlive => true;

View File

@@ -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('&amp;', '&')
// .replaceAll('&lt;', '<')
// .replaceAll('&gt;', '>')
// .replaceAll('&quot;', '"')
// .replaceAll('&apos;', "'")
// .replaceAll('&nbsp;', ' ');
// 构建正则表达式
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);
}

View File

@@ -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 ? '点赞成功' : '取消赞');

View File

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

View File

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

View File

@@ -50,15 +50,6 @@ class ScrollAppBar extends StatelessWidget {
],
),
),
// actions: [
// IconButton(
// onPressed: () {},
// icon: const Icon(
// Icons.share,
// size: 20,
// )),
// const SizedBox(width: 12)
// ],
),
),
),

View File

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

View File

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

View File

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

View File

@@ -160,14 +160,6 @@ class _WhisperDetailPageState
style: TextStyle(fontSize: 14),
),
),
// ListTile(
// onTap: () {
// Get.back();
// },
// dense: true,
// title: const Text('删除',
// style: TextStyle(fontSize: 14)),
// ),
],
),
);

View File

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