opt handle data

Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
bggRGjQaUbCoE
2025-05-29 21:11:57 +08:00
parent c9450992d9
commit 9a63e23478
24 changed files with 147 additions and 116 deletions

4
.gitignore vendored
View File

@@ -135,4 +135,6 @@ app.*.symbols
!/dev/ci/**/Gemfile.lock
!.vscode/settings.json
/lib/build_config.dart
/lib/build_config.dart
devtools_options.yaml

View File

@@ -10,6 +10,7 @@ import 'package:PiliPlus/utils/storage.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:easy_debounce/easy_throttle.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
@@ -295,11 +296,13 @@ class _InteractiveviewerGalleryState extends State<InteractiveviewerGallery>
final item = widget.sources[index];
return GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: onClose,
onTap: () => EasyThrottle.throttle(
'preview', const Duration(milliseconds: 555), onClose),
onDoubleTapDown: (TapDownDetails details) {
_doubleTapLocalPosition = details.localPosition;
},
onDoubleTap: onDoubleTap,
onDoubleTap: () => EasyThrottle.throttle(
'preview', const Duration(milliseconds: 555), onDoubleTap),
onLongPress: item.sourceType == SourceType.fileImage
? null
: () => onLongPress(item),
@@ -500,14 +503,14 @@ class _InteractiveviewerGalleryState extends State<InteractiveviewerGallery>
builder: (context) {
return AlertDialog(
clipBehavior: Clip.hardEdge,
contentPadding: const EdgeInsets.fromLTRB(0, 12, 0, 12),
contentPadding: const EdgeInsets.symmetric(vertical: 12),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
ListTile(
onTap: () {
DownloadUtils.onShareImg(item.url);
Get.back();
DownloadUtils.onShareImg(item.url);
},
dense: true,
title: const Text('分享', style: TextStyle(fontSize: 14)),

View File

@@ -38,6 +38,9 @@ class PlDanmakuController {
if (result.isSuccess) {
final data = result.data;
if (data.state == 1) {
plPlayerController.dmState.add(cid);
}
if (data.elems.isNotEmpty) {
final Map<String, int> counts = {};
if (mergeDanmaku) {

View File

@@ -46,8 +46,9 @@ class DanmakuBlockController extends GetxController
var result = await DanmakuFilterHttp.danmakuFilterDel(ids: id);
SmartDialog.dismiss();
if (result['status']) {
ruleTypes[type]!.remove(id);
ruleTypes.refresh();
ruleTypes
..[type]!.remove(id)
..refresh();
}
SmartDialog.showToast(result['msg']);
}
@@ -60,8 +61,9 @@ class DanmakuBlockController extends GetxController
SmartDialog.dismiss();
if (result['status']) {
SimpleRule rule = result['data'];
ruleTypes[type]![rule.id] = rule.filter;
ruleTypes.refresh();
ruleTypes
..[type]![rule.id] = rule.filter
..refresh();
SmartDialog.showToast('添加成功');
} else {
SmartDialog.showToast(result['msg']);

View File

@@ -108,8 +108,9 @@ class DynamicsController extends GetxController
if (isQuerying) return;
isQuerying = true;
if (!isLogin.value) {
upData.value.errMsg = '账号未登录';
upData.refresh();
upData
..value.errMsg = '账号未登录'
..refresh();
}
upData.value.errMsg = null;
if (GStorage.setting
@@ -125,11 +126,13 @@ class DynamicsController extends GetxController
final res0 = await f1;
if (!res0.isSuccess) {
SmartDialog.showToast("获取关注动态失败:$res0");
upData.value.errMsg = (res0 as Error).errMsg;
upData.refresh();
upData
..value.errMsg = (res0 as Error).errMsg
..refresh();
} else {
upData.value.liveUsers = res0.data.liveUsers;
upData.refresh();
upData
..value.liveUsers = res0.data.liveUsers
..refresh();
hasUpdatedUps = res0.data.upList!;
}
List<UpItem> allFollowedUps = <UpItem>[];
@@ -151,8 +154,9 @@ class DynamicsController extends GetxController
allFollowedUpsPage += 1;
allFollowedUpsTotal = res1.data.total!;
}
upData.value.upList = hasUpdatedUps + allFollowedUps;
upData.refresh();
upData
..value.upList = hasUpdatedUps + allFollowedUps
..refresh();
} else {
var res = await DynamicsHttp.followUp();
if (res.isSuccess) {
@@ -161,8 +165,9 @@ class DynamicsController extends GetxController
mid.value = -1;
}
} else {
upData.value.errMsg = (res as Error).errMsg;
upData.refresh();
upData
..value.errMsg = (res as Error).errMsg
..refresh();
}
}
isQuerying = false;

View File

@@ -200,14 +200,14 @@ class _CreateDynPanelState extends CommonPublishPageState<CreateDynPanel> {
);
}
Widget _buildImageList(ThemeData theme) => Obx(
() => SizedBox(
height: 100,
width: double.infinity,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Row(
Widget _buildImageList(ThemeData theme) => SizedBox(
height: 100,
width: double.infinity,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Obx(
() => Row(
spacing: 10,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
@@ -504,13 +504,11 @@ class _CreateDynPanelState extends CommonPublishPageState<CreateDynPanel> {
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: Obx(
() => ToolbarIconButton(
onPressed: () {
updatePanelType(
panelType.value == PanelType.emoji
? PanelType.keyboard
: PanelType.emoji,
);
},
onPressed: () => updatePanelType(
panelType.value == PanelType.emoji
? PanelType.keyboard
: PanelType.emoji,
),
icon: const Icon(Icons.emoji_emotions, size: 22),
tooltip: '表情',
selected: panelType.value == PanelType.emoji,

View File

@@ -80,9 +80,11 @@ class FavPgcController
try {
final ctr = Get.find<FavPgcController>(tag: '$type$followStatus');
if (ctr.loadingState.value.isSuccess) {
ctr.loadingState.value.data!
.insertAll(0, updateList.map((item) => item..checked = null));
ctr.loadingState.refresh();
ctr.loadingState
..value
.data!
.insertAll(0, updateList.map((item) => item..checked = null))
..refresh();
ctr.allSelected.value = false;
}
} catch (e) {
@@ -104,8 +106,9 @@ class FavPgcController
try {
final ctr = Get.find<FavPgcController>(tag: '$type$followStatus');
if (ctr.loadingState.value.isSuccess) {
ctr.loadingState.value.data!.insert(0, item);
ctr.loadingState.refresh();
ctr.loadingState
..value.data?.insert(0, item)
..refresh();
ctr.allSelected.value = false;
}
} catch (e) {

View File

@@ -83,8 +83,9 @@ class _FavVideoPageState extends State<FavVideoPage>
},
);
if (res == true) {
_favController.loadingState.value.data!.removeAt(index);
_favController.loadingState.refresh();
_favController.loadingState
..value.data!.removeAt(index)
..refresh();
}
},
);

View File

@@ -1,4 +1,5 @@
import 'package:PiliPlus/common/widgets/scroll_physics.dart';
import 'package:PiliPlus/http/loading_state.dart';
import 'package:PiliPlus/models/common/fav_type.dart';
import 'package:PiliPlus/models/user/fav_folder.dart';
import 'package:PiliPlus/pages/fav/article/controller.dart';
@@ -59,12 +60,16 @@ class _FavPageState extends State<FavPage> with SingleTickerProviderStateMixin {
onPressed: () => Get.toNamed('/createFav')?.then(
(data) {
if (data != null) {
List<FavFolderItemData> list =
List<FavFolderItemData>? list =
_favController.loadingState.value.isSuccess
? _favController.loadingState.value.data!
: <FavFolderItemData>[];
list.insert(list.isNotEmpty ? 1 : 0, data);
_favController.loadingState.refresh();
? _favController.loadingState.value.data
: null;
if (list?.isNotEmpty == true) {
list!.insert(1, data);
_favController.loadingState.refresh();
} else {
_favController.loadingState.value = Success([data]);
}
}
},
),

View File

@@ -35,8 +35,9 @@ class FollowChildController
tagid == null &&
isRefresh &&
controller!.followState.value.isSuccess) {
controller!.tabs[0].count = response.response.total;
controller!.tabs.refresh();
controller!.tabs
..[0].count = response.response.total
..refresh();
}
} catch (_) {}
}

View File

@@ -94,10 +94,9 @@ class _FollowChildPageState extends State<FollowChildPage>
isOwner: widget.controller?.isOwner,
onSelect: widget.onSelect,
callback: (attr) {
List<FollowItemModel> list =
_followController.loadingState.value.data!;
list[index].attribute = attr == 0 ? -1 : 0;
_followController.loadingState.refresh();
_followController.loadingState
..value.data![index].attribute = attr == 0 ? -1 : 0
..refresh();
},
);
},

View File

@@ -73,8 +73,9 @@ class FollowController extends GetxController with GetTickerProviderStateMixin {
Future<void> onUpdateTag(int index, tagid, String tagName) async {
final res = await MemberHttp.updateFollowTag(tagid, tagName);
if (res['status']) {
tabs[index].name = tagName;
tabs.refresh();
tabs
..[index].name = tagName
..refresh();
SmartDialog.showToast('修改成功');
} else {
SmartDialog.showToast(res['msg']);

View File

@@ -104,10 +104,11 @@ class LaterController extends MultiSelectController<Map, HotVideoItemModel> {
Get.back();
var res = await UserHttp.toViewDel(aids: [aid]);
if (res['status']) {
loadingState.value.data!.removeAt(index);
baseCtr.counts[laterViewType] =
baseCtr.counts[laterViewType]! - 1;
loadingState.refresh();
loadingState
..value.data!.removeAt(index)
..refresh();
}
SmartDialog.showToast(res['msg']);
},

View File

@@ -71,8 +71,9 @@ class MemberFavoriteCtr extends CommonDataController {
?.map((item) => SpaceFavItemModel.fromJson(item))
.toList() ??
<SpaceFavItemModel>[];
first.value.mediaListResponse?.list?.addAll(list);
first.refresh();
first
..value.mediaListResponse?.list?.addAll(list)
..refresh();
} else {
firstEnd.value = true;
}
@@ -97,8 +98,9 @@ class MemberFavoriteCtr extends CommonDataController {
?.map((item) => SpaceFavItemModel.fromJson(item))
.toList() ??
<SpaceFavItemModel>[];
second.value.mediaListResponse?.list?.addAll(list);
second.refresh();
second
..value.mediaListResponse?.list?.addAll(list)
..refresh();
} else {
secondEnd.value = true;
}

View File

@@ -122,9 +122,9 @@ class _MemberFavoriteState extends State<MemberFavorite>
item: item,
callback: (res) {
if (res == true) {
_controller.first.value.mediaListResponse?.list
?.remove(item);
_controller.first.refresh();
_controller
..first.value.mediaListResponse?.list?.remove(item)
..first.refresh();
}
},
),

View File

@@ -105,17 +105,18 @@ class _RcmdPageState extends CommonPageState<RcmdPage, RcmdController>
controller.lastRefreshAt =
controller.lastRefreshAt! - 1;
}
controller.loadingState.value.data!
.removeAt(actualIndex);
controller.loadingState.refresh();
controller.loadingState
..value.data!.removeAt(actualIndex)
..refresh();
},
);
} else {
return VideoCardV(
videoItem: response[index],
onRemove: () {
controller.loadingState.value.data!.removeAt(index);
controller.loadingState.refresh();
controller.loadingState
..value.data!.removeAt(index)
..refresh();
},
);
}

View File

@@ -938,6 +938,10 @@ class VideoDetailController extends GetxController
/// 发送弹幕
Future<void> showShootDanmakuSheet() async {
if (plPlayerController.dmState.contains(cid.value)) {
SmartDialog.showToast('UP主已关闭弹幕');
return;
}
bool isPlaying =
plPlayerController.playerStatus.status.value == PlayerStatus.playing;
if (isPlaying) {

View File

@@ -352,12 +352,10 @@ class BangumiIntroController extends GetxController {
// 选择文件夹
void onChoose(bool checkValue, int index) {
feedBack();
List<FavFolderItemData> datalist = favFolderData.value.list!;
datalist[index].favState = checkValue ? 1 : 0;
datalist[index].mediaCount = checkValue
? datalist[index].mediaCount! + 1
: datalist[index].mediaCount! - 1;
favFolderData.value.list = datalist;
FavFolderItemData item = favFolderData.value.list![index];
item
..favState = checkValue ? 1 : 0
..mediaCount = checkValue ? item.mediaCount! + 1 : item.mediaCount! - 1;
favFolderData.refresh();
}

View File

@@ -558,12 +558,10 @@ class VideoIntroController extends GetxController {
// 选择文件夹
void onChoose(bool checkValue, int index) {
feedBack();
List<FavFolderItemData> datalist = favFolderData.value.list!;
datalist[index].favState = checkValue ? 1 : 0;
datalist[index].mediaCount = checkValue
? datalist[index].mediaCount! + 1
: datalist[index].mediaCount! - 1;
favFolderData.value.list = datalist;
FavFolderItemData item = favFolderData.value.list![index];
item
..favState = checkValue ? 1 : 0
..mediaCount = checkValue ? item.mediaCount! + 1 : item.mediaCount! - 1;
favFolderData.refresh();
}

View File

@@ -332,9 +332,9 @@ class _HorizontalMemberPageState extends State<HorizontalMemberPage> {
mid: widget.mid,
isFollow: memberInfoModel.isFollowed ?? false,
callback: (attribute) {
_controller.userState.value.data.isFollowed =
attribute != 0;
_controller.userState.refresh();
_controller
..userState.value.data.isFollowed = attribute != 0
..userState.refresh();
},
);
}

View File

@@ -354,10 +354,10 @@ class _VideoReplyReplyPanelState
if (res != null) {
_savedReplies.remove(key);
ReplyInfo replyInfo = RequestUtils.replyCast(res);
_videoReplyReplyController.loadingState.value.dataOrNull
?.insert(index + 1, replyInfo);
_videoReplyReplyController.count.value += 1;
_videoReplyReplyController.loadingState.refresh();
_videoReplyReplyController
..count.value += 1
..loadingState.value.dataOrNull?.insert(index + 1, replyInfo)
..loadingState.refresh();
if (_videoReplyReplyController.enableCommAntifraud && mounted) {
_videoReplyReplyController.onCheckReply(context, replyInfo);
}

View File

@@ -2179,25 +2179,17 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
if (isSeason) {
// reverse season
videoIntroController.videoDetail.value.ugcSeason!
.sections![videoDetailController.seasonIndex.value].isReversed =
!videoIntroController.videoDetail.value.ugcSeason!
.sections![videoDetailController.seasonIndex.value].isReversed;
videoIntroController.videoDetail.value.ugcSeason!
.sections![videoDetailController.seasonIndex.value].episodes =
videoIntroController
.videoDetail
.value
.ugcSeason!
.sections![videoDetailController.seasonIndex.value]
.episodes!
.reversed
.toList();
final item = videoIntroController.videoDetail.value.ugcSeason!
.sections![videoDetailController.seasonIndex.value];
item
..isReversed = !item.isReversed
..episodes = item.episodes!.reversed.toList();
if (videoDetailController.plPlayerController.reverseFromFirst.not) {
// keep current episode
videoDetailController.seasonIndex.refresh();
videoDetailController.cid.refresh();
videoDetailController
..seasonIndex.refresh()
..cid.refresh();
} else {
// switch to first episode
dynamic episode = videoIntroController.videoDetail.value.ugcSeason!
@@ -2206,16 +2198,17 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
changeEpisode(episode);
videoDetailController.seasonCid = episode.cid;
} else {
videoDetailController.seasonIndex.refresh();
videoDetailController.cid.refresh();
videoDetailController
..seasonIndex.refresh()
..cid.refresh();
}
}
} else {
// reverse part
videoIntroController.videoDetail.value.isPageReversed =
!videoIntroController.videoDetail.value.isPageReversed;
videoIntroController.videoDetail.value.pages =
videoIntroController.videoDetail.value.pages!.reversed.toList();
final item = videoIntroController.videoDetail.value;
item
..isPageReversed = !item.isPageReversed
..pages = item.pages!.reversed.toList();
if (videoDetailController.plPlayerController.reverseFromFirst.not) {
// keep current episode
videoDetailController.cid.refresh();

View File

@@ -1911,13 +1911,22 @@ class HeaderControlState extends State<HeaderControl> {
builder: (context, constraints) {
return Obx(
() {
String title = videoIntroController
.videoDetail.value.pages
?.firstWhereOrNull((e) =>
e.cid == videoDetailCtr.cid.value)
?.pagePart ??
videoIntroController
.videoDetail.value.title!;
String title;
if (videoIntroController
.videoDetail.value.videos ==
1) {
title = videoIntroController
.videoDetail.value.title!;
} else {
title = videoIntroController
.videoDetail.value.pages
?.firstWhereOrNull((e) =>
e.cid == videoDetailCtr.cid.value)
?.pagePart ??
videoIntroController
.videoDetail.value.title!;
}
final textPainter = TextPainter(
text: TextSpan(
text: title,

View File

@@ -249,6 +249,7 @@ class PlPlayerController {
// 关联弹幕控制器
DanmakuController? danmakuController;
bool showDanmaku = true;
Set<int> dmState = <int>{};
late final mergeDanmaku = GStorage.mergeDanmaku;
// 弹幕相关配置
late Set<int> blockTypes;
@@ -1521,6 +1522,7 @@ class PlPlayerController {
}
return;
}
dmState.clear();
_playerCount.value = 0;
Utils.channel.setMethodCallHandler(null);
pause();