From 79514e4bfba73f86111156ceb4176c0498846289 Mon Sep 17 00:00:00 2001 From: guozhigq Date: Tue, 22 Oct 2024 23:58:38 +0800 Subject: [PATCH 01/15] mod: history search api --- lib/http/api.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/http/api.dart b/lib/http/api.dart index 3d292345..787b036b 100644 --- a/lib/http/api.dart +++ b/lib/http/api.dart @@ -175,7 +175,7 @@ class Api { static const String delHistory = '/x/v2/history/delete'; // 搜索历史记录 - static const String searchHistory = '/x/web-goblin/history/search'; + static const String searchHistory = '/x/web-interface/history/search'; // 热搜 static const String hotSearchList = From c6fcbb8566abc2f197375f93d56152382af28a19 Mon Sep 17 00:00:00 2001 From: guozhigq Date: Wed, 23 Oct 2024 23:00:59 +0800 Subject: [PATCH 02/15] fix: layout --- lib/pages/mine/view.dart | 86 ++++++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 44 deletions(-) diff --git a/lib/pages/mine/view.dart b/lib/pages/mine/view.dart index b96c095a..c2925f6e 100644 --- a/lib/pages/mine/view.dart +++ b/lib/pages/mine/view.dart @@ -75,60 +75,58 @@ class _MinePageState extends State parent: BouncingScrollPhysics()), child: Padding( padding: const EdgeInsets.only(bottom: 110), - child: Expanded( - child: Column( - children: [ - Obx(() => _buildProfileSection(context, ctr.userInfo.value)), - const SizedBox(height: 10), - FutureBuilder( - future: _futureBuilderFuture, - builder: (context, snapshot) { - if (snapshot.connectionState == ConnectionState.done) { - if (snapshot.data == null) { - return const SizedBox(); - } - if (snapshot.data['status']) { - return Obx( - () => _buildStatsSection( - context, - ctr.userStat.value, - ), - ); - } else { - return _buildStatsSection( + child: Column( + children: [ + Obx(() => _buildProfileSection(context, ctr.userInfo.value)), + const SizedBox(height: 10), + FutureBuilder( + future: _futureBuilderFuture, + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.done) { + if (snapshot.data == null) { + return const SizedBox(); + } + if (snapshot.data['status']) { + return Obx( + () => _buildStatsSection( context, ctr.userStat.value, - ); - } + ), + ); } else { return _buildStatsSection( context, ctr.userStat.value, ); } - }, - ), - _buildMenuSection(context), - Obx( - () => Visibility( - visible: ctr.userLogin.value, - child: Divider( - height: 25, - color: Theme.of(context).dividerColor.withOpacity(0.1), - ), + } else { + return _buildStatsSection( + context, + ctr.userStat.value, + ); + } + }, + ), + _buildMenuSection(context), + Obx( + () => Visibility( + visible: ctr.userLogin.value, + child: Divider( + height: 25, + color: Theme.of(context).dividerColor.withOpacity(0.1), ), ), - Obx( - () => ctr.userLogin.value - ? _buildFavoritesSection(context) - : const SizedBox(), - ), - SizedBox( - height: MediaQuery.of(context).padding.bottom + - kBottomNavigationBarHeight, - ) - ], - ), + ), + Obx( + () => ctr.userLogin.value + ? _buildFavoritesSection(context) + : const SizedBox(), + ), + SizedBox( + height: MediaQuery.of(context).padding.bottom + + kBottomNavigationBarHeight, + ) + ], ), ), ), From 55ae549b988faac13dd38f22c6335639a58f6008 Mon Sep 17 00:00:00 2001 From: guozhigq Date: Thu, 24 Oct 2024 00:35:32 +0800 Subject: [PATCH 03/15] fix: reply model null error --- lib/models/video/reply/data.dart | 2 +- lib/pages/dynamics/detail/view.dart | 13 ++++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/lib/models/video/reply/data.dart b/lib/models/video/reply/data.dart index 69a13d88..fdb17267 100644 --- a/lib/models/video/reply/data.dart +++ b/lib/models/video/reply/data.dart @@ -73,7 +73,7 @@ class ReplyCursor { isEnd = json['is_end']; mode = json['mode']; modeText = json['mode_text']; - allCount = json['all_count']; + allCount = json['all_count'] ?? 0; supportMode = json['support_mode'].cast(); name = json['name']; paginationReply = json['pagination_reply'] != null diff --git a/lib/pages/dynamics/detail/view.dart b/lib/pages/dynamics/detail/view.dart index 7e5f1562..395f89b8 100644 --- a/lib/pages/dynamics/detail/view.dart +++ b/lib/pages/dynamics/detail/view.dart @@ -31,7 +31,7 @@ class _DynamicDetailPageState extends State with TickerProviderStateMixin { late DynamicDetailController _dynamicDetailController; late AnimationController fabAnimationCtr; - Future? _futureBuilderFuture; + late Future _futureBuilderFuture; late StreamController titleStreamC = StreamController.broadcast(); // appBar title late ScrollController scrollController; @@ -278,8 +278,8 @@ class _DynamicDetailPageState extends State future: _futureBuilderFuture, builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.done) { - Map data = snapshot.data as Map; - if (snapshot.data['status']) { + Map? data = snapshot.data; + if (data != null && snapshot.data['status']) { RxList replyList = _dynamicDetailController.replyList; // 请求成功 @@ -345,8 +345,11 @@ class _DynamicDetailPageState extends State } else { // 请求错误 return HttpError( - errMsg: data['msg'], - fn: () => setState(() {}), + errMsg: data?['msg'] ?? '请求异常', + fn: () => setState(() { + _futureBuilderFuture = + _dynamicDetailController.queryReplyList(); + }), ); } } else { From e74d326c7a6c4ed7052c8f5521aaea09082222b9 Mon Sep 17 00:00:00 2001 From: guozhigq Date: Fri, 25 Oct 2024 00:03:24 +0800 Subject: [PATCH 04/15] fix: search history cache --- lib/pages/search/controller.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/pages/search/controller.dart b/lib/pages/search/controller.dart index 64590934..964f8625 100644 --- a/lib/pages/search/controller.dart +++ b/lib/pages/search/controller.dart @@ -84,6 +84,7 @@ class SSearchController extends GetxController { // 手动刷新 historyList.refresh(); localCache.put('cacheList', historyCacheList); + GlobalDataCache().historyCacheList = historyCacheList; searchFocusNode.unfocus(); Get.toNamed('/searchResult', parameters: {'keyword': searchKeyWord.value}); } @@ -135,6 +136,7 @@ class SSearchController extends GetxController { historyCacheList = []; historyList.refresh(); localCache.put('cacheList', []); + GlobalDataCache().historyCacheList = []; SmartDialog.showToast('搜索历史已清空'); } } From a8f228fab7171dceada4bcc1571d371ff931a704 Mon Sep 17 00:00:00 2001 From: guozhigq Date: Fri, 25 Oct 2024 00:06:20 +0800 Subject: [PATCH 05/15] fix: null error --- lib/pages/whisper/view.dart | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/pages/whisper/view.dart b/lib/pages/whisper/view.dart index cbe4d938..8e61bab3 100644 --- a/lib/pages/whisper/view.dart +++ b/lib/pages/whisper/view.dart @@ -227,8 +227,8 @@ class SessionItem extends StatelessWidget { '/whisperDetail', parameters: { 'talkerId': sessionItem.talkerId.toString(), - 'name': sessionItem.accountInfo.name, - 'face': sessionItem.accountInfo.face ?? '', + 'name': sessionItem.accountInfo?.name ?? '', + 'face': sessionItem.accountInfo?.face ?? '', 'mid': (sessionItem.accountInfo?.mid ?? 0).toString(), 'heroTag': heroTag, }, @@ -244,11 +244,11 @@ class SessionItem extends StatelessWidget { width: 45, height: 45, type: 'avatar', - src: sessionItem.accountInfo.face ?? '', + src: sessionItem.accountInfo?.face ?? '', ), ), ), - title: Text(sessionItem.accountInfo.name), + title: Text(sessionItem.accountInfo?.name ?? ''), subtitle: Text( msgStatus == 1 ? '你撤回了一条消息' From 3aca6cecc2dc0a85e6cac636ecdc52cfde4066f4 Mon Sep 17 00:00:00 2001 From: guozhigq Date: Sat, 26 Oct 2024 00:34:23 +0800 Subject: [PATCH 06/15] fix: member article cover url null --- lib/pages/member_article/view.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pages/member_article/view.dart b/lib/pages/member_article/view.dart index 0728a7b6..67cb8b96 100644 --- a/lib/pages/member_article/view.dart +++ b/lib/pages/member_article/view.dart @@ -117,7 +117,7 @@ class _MemberArticlePageState extends State { width: 50, height: 50, type: 'emote', - src: item.cover['url'], + src: item?.cover?['url'] ?? '', ), title: Text( item.content, From 7485400894138af441e51803b021895e9c993d9b Mon Sep 17 00:00:00 2001 From: guozhigq Date: Sun, 27 Oct 2024 00:45:20 +0800 Subject: [PATCH 07/15] fix: loadMore reply --- lib/models/video/reply/item.dart | 3 +++ lib/pages/video/detail/reply/widgets/reply_item.dart | 12 +++--------- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/lib/models/video/reply/item.dart b/lib/models/video/reply/item.dart index 3ae811ec..1fa05bec 100644 --- a/lib/models/video/reply/item.dart +++ b/lib/models/video/reply/item.dart @@ -11,6 +11,7 @@ class ReplyItemModel { this.parent, this.dialog, this.count, + this.rcount, this.floor, this.state, this.fansgrade, @@ -41,6 +42,7 @@ class ReplyItemModel { int? parent; int? dialog; int? count; + int? rcount; int? floor; int? state; int? fansgrade; @@ -72,6 +74,7 @@ class ReplyItemModel { parent = json['parent']; dialog = json['dialog']; count = json['count']; + rcount = json['rcount'] ?? 0; floor = json['floor']; state = json['state']; fansgrade = json['fansgrade']; diff --git a/lib/pages/video/detail/reply/widgets/reply_item.dart b/lib/pages/video/detail/reply/widgets/reply_item.dart index 051c6075..f6863466 100644 --- a/lib/pages/video/detail/reply/widgets/reply_item.dart +++ b/lib/pages/video/detail/reply/widgets/reply_item.dart @@ -1,6 +1,5 @@ import 'dart:math'; -import 'package:appscheme/appscheme.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -60,9 +59,7 @@ class ReplyItem extends StatelessWidget { return; } feedBack(); - if (replyReply != null) { - replyReply!(replyItem, null, replyItem!.replies!.isNotEmpty); - } + replyReply?.call(replyItem, null, replyItem!.rcount! > 0); }, onLongPress: () { if (replySave!) { @@ -289,9 +286,7 @@ class ReplyItem extends StatelessWidget { // 操作区域 bottonAction(context, replyItem!.replyControl, replySave), // 一楼的评论 - if ((replyItem!.replyControl!.isShow! || - replyItem!.replies!.isNotEmpty) && - showReplyRow!) ...[ + if ((replyItem!.rcount! > 0) && showReplyRow!) ...[ Padding( padding: const EdgeInsets.only(top: 5, bottom: 12), child: ReplyItemRow( @@ -408,8 +403,7 @@ class ReplyItemRow extends StatelessWidget { @override Widget build(BuildContext context) { - final bool isShow = replyControl!.isShow!; - final int extraRow = replyControl != null && isShow ? 1 : 0; + final int extraRow = replyItem!.rcount! > 0 ? 1 : 0; ColorScheme colorScheme = Theme.of(context).colorScheme; TextTheme textTheme = Theme.of(context).textTheme; From 16a8cc8d68426bef01fbc1844e027b23c6fce1a8 Mon Sep 17 00:00:00 2001 From: guozhigq Date: Sun, 27 Oct 2024 14:39:21 +0800 Subject: [PATCH 08/15] opt: bangumi follow status --- lib/http/api.dart | 3 + lib/http/bangumi.dart | 48 +++++++ .../bangumi/introduction/controller.dart | 61 ++++++++- lib/pages/bangumi/introduction/view.dart | 120 +++++++++++++++--- lib/utils/route_push.dart | 2 +- 5 files changed, 206 insertions(+), 28 deletions(-) diff --git a/lib/http/api.dart b/lib/http/api.dart index 787b036b..04983339 100644 --- a/lib/http/api.dart +++ b/lib/http/api.dart @@ -604,4 +604,7 @@ class Api { /// 图片上传 static const String uploadImage = '/x/dynamic/feed/draw/upload_bfs'; + + /// 更新追番状态 + static const String updateBangumiStatus = '/pgc/web/follow/status/update'; } diff --git a/lib/http/bangumi.dart b/lib/http/bangumi.dart index 91508682..e9ccce96 100644 --- a/lib/http/bangumi.dart +++ b/lib/http/bangumi.dart @@ -1,5 +1,8 @@ +import 'dart:convert'; import '../models/bangumi/list.dart'; import 'index.dart'; +import 'package:html/parser.dart' as html_parser; +import 'package:html/dom.dart' as html_dom; class BangumiHttp { static Future bangumiList({int? page}) async { @@ -33,4 +36,49 @@ class BangumiHttp { }; } } + + // 获取追番状态 + static Future bangumiStatus({required int seasonId}) async { + var res = await Request() + .get('https://www.bilibili.com/bangumi/play/ss$seasonId'); + html_dom.Document document = html_parser.parse(res.data); + // 查找 id 为 __NEXT_DATA__ 的 script 元素 + html_dom.Element? scriptElement = + document.querySelector('script#\\__NEXT_DATA__'); + if (scriptElement != null) { + // 提取 script 元素的内容 + String scriptContent = scriptElement.text; + final dynamic scriptContentJson = jsonDecode(scriptContent); + Map followState = scriptContentJson['props']['pageProps']['followState']; + return { + 'status': true, + 'data': { + 'isFollowed': followState['isFollowed'], + 'followStatus': followState['followStatus'] + } + }; + } else { + print('Script element with id "__NEXT_DATA__" not found.'); + } + } + + // 更新追番状态 + static Future updateBangumiStatus({ + required int seasonId, + required int status, + }) async { + var res = await Request().post(Api.updateBangumiStatus, data: { + 'season_id': seasonId, + 'status': status, + }); + if (res.data['code'] == 0) { + return {'status': true, 'data': res.data['data']}; + } else { + return { + 'status': false, + 'data': [], + 'msg': res.data['message'], + }; + } + } } diff --git a/lib/pages/bangumi/introduction/controller.dart b/lib/pages/bangumi/introduction/controller.dart index cf428c28..f2d7807e 100644 --- a/lib/pages/bangumi/introduction/controller.dart +++ b/lib/pages/bangumi/introduction/controller.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:get/get.dart'; import 'package:hive/hive.dart'; +import 'package:pilipala/http/bangumi.dart'; import 'package:pilipala/http/constants.dart'; import 'package:pilipala/http/search.dart'; import 'package:pilipala/http/video.dart'; @@ -52,17 +53,27 @@ class BangumiIntroController extends GetxController { Rx favFolderData = FavFolderData().obs; List addMediaIdsNew = []; List delMediaIdsNew = []; - // 关注状态 默认未关注 - RxMap followStatus = {}.obs; + // 追番状态 1想看 2在看 3已看 + RxBool isFollowed = false.obs; + RxInt followStatus = 1.obs; int _tempThemeValue = -1; var userInfo; PersistentBottomSheetController? bottomSheetController; + List> followStatusList = [ + {'title': '标记为 「想看」', 'status': 1}, + {'title': '标记为 「在看」', 'status': 2}, + {'title': '标记为 「已看」', 'status': 3}, + {'title': '取消追番', 'status': -1}, + ]; @override void onInit() { super.onInit(); userInfo = userInfoCache.get('userInfoCache'); userLogin = userInfo != null; + if (userLogin && seasonId != null) { + bangumiStatus(); + } } // 获取番剧简介&选集 @@ -239,15 +250,22 @@ class BangumiIntroController extends GetxController { // 追番 Future bangumiAdd() async { - var result = - await VideoHttp.bangumiAdd(seasonId: bangumiDetail.value.seasonId); + var result = await VideoHttp.bangumiAdd( + seasonId: seasonId ?? bangumiDetail.value.seasonId); + if (result['status']) { + followStatus.value = 2; + isFollowed.value = true; + } SmartDialog.showToast(result['msg']); } // 取消追番 Future bangumiDel() async { - var result = - await VideoHttp.bangumiDel(seasonId: bangumiDetail.value.seasonId); + var result = await VideoHttp.bangumiDel( + seasonId: seasonId ?? bangumiDetail.value.seasonId); + if (result['status']) { + isFollowed.value = false; + } SmartDialog.showToast(result['msg']); } @@ -315,4 +333,35 @@ class BangumiIntroController extends GetxController { hiddenEpisodeBottomSheet() { bottomSheetController?.close(); } + + // 获取追番状态 + Future bangumiStatus() async { + var result = await BangumiHttp.bangumiStatus(seasonId: seasonId!); + if (result['status']) { + followStatus.value = result['data']['followStatus']; + isFollowed.value = result['data']['isFollowed']; + } + return result; + } + + // 更新追番状态 + Future updateBangumiStatus(int status) async { + Get.back(); + if (status == -1) { + bangumiDel(); + } else { + var result = await BangumiHttp.bangumiStatus(seasonId: seasonId!); + if (result['status']) { + followStatus.value = status; + final title = followStatusList.firstWhere( + (e) => e['status'] == status, + orElse: () => {'title': '未知状态'}, + )['title']; + SmartDialog.showToast('追番状态$title'); + } else { + SmartDialog.showToast(result['msg']); + } + return result; + } + } } diff --git a/lib/pages/bangumi/introduction/view.dart b/lib/pages/bangumi/introduction/view.dart index b79b37b8..b90ef992 100644 --- a/lib/pages/bangumi/introduction/view.dart +++ b/lib/pages/bangumi/introduction/view.dart @@ -259,27 +259,11 @@ class _BangumiInfoState extends State { ), ), const SizedBox(width: 20), - SizedBox( - width: 34, - height: 34, - child: IconButton( - style: ButtonStyle( - padding: MaterialStateProperty.all( - EdgeInsets.zero), - backgroundColor: - MaterialStateProperty.resolveWith( - (Set states) { - return t.colorScheme.primaryContainer - .withOpacity(0.7); - }), - ), - onPressed: () => - bangumiIntroController.bangumiAdd(), - icon: Icon( - Icons.favorite_border_rounded, - color: t.colorScheme.primary, - size: 22, - ), + Obx( + () => BangumiStatusWidget( + ctr: bangumiIntroController, + isFollowed: + bangumiIntroController.isFollowed.value, ), ), ], @@ -426,3 +410,97 @@ class _BangumiInfoState extends State { }); } } + +// 追番状态 +class BangumiStatusWidget extends StatelessWidget { + final BangumiIntroController ctr; + final bool isFollowed; + + const BangumiStatusWidget({ + Key? key, + required this.ctr, + required this.isFollowed, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + ColorScheme colorScheme = Theme.of(context).colorScheme; + + void updateFollowStatus() { + showModalBottomSheet( + context: context, + useRootNavigator: true, + isScrollControlled: true, + builder: (context) { + return morePanel(context, ctr); + }, + ); + } + + return Obx( + () => SizedBox( + width: 34, + height: 34, + child: IconButton( + style: ButtonStyle( + padding: MaterialStateProperty.all(EdgeInsets.zero), + backgroundColor: + MaterialStateProperty.resolveWith((Set states) { + return ctr.isFollowed.value + ? colorScheme.primaryContainer.withOpacity(0.7) + : colorScheme.outlineVariant.withOpacity(0.7); + }), + ), + onPressed: + isFollowed ? () => updateFollowStatus() : () => ctr.bangumiAdd(), + icon: Icon( + ctr.isFollowed.value + ? Icons.favorite + : Icons.favorite_border_rounded, + color: ctr.isFollowed.value + ? colorScheme.primary + : colorScheme.outline, + size: 22, + ), + ), + ), + ); + } + + Widget morePanel(BuildContext context, BangumiIntroController ctr) { + return Container( + padding: EdgeInsets.only(bottom: MediaQuery.of(context).padding.bottom), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + InkWell( + onTap: () => Get.back(), + child: Container( + height: 35, + padding: const EdgeInsets.only(bottom: 2), + child: Center( + child: Container( + width: 32, + height: 3, + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.outline, + borderRadius: const BorderRadius.all(Radius.circular(3))), + ), + ), + ), + ), + ...ctr.followStatusList + .map( + (e) => ListTile( + onTap: () => ctr.updateBangumiStatus(e['status']), + selected: ctr.followStatus == e['status'], + title: Text(e['title']), + ), + ) + .toList(), + const SizedBox(height: 20), + ], + ), + ); + } +} diff --git a/lib/utils/route_push.dart b/lib/utils/route_push.dart index 9ee28846..e639327d 100644 --- a/lib/utils/route_push.dart +++ b/lib/utils/route_push.dart @@ -31,7 +31,7 @@ class RoutePush { }; arguments['heroTag'] = heroTag ?? Utils.makeHeroTag(cid); Get.toNamed( - '/video?bvid=$bvid&cid=$cid&epId=$epId', + '/video?bvid=$bvid&cid=$cid&epId=$epId&seasonId=$seasonId', arguments: arguments, ); } else { From f21ad55f50726b98682efca6ad7ddf08b11016c7 Mon Sep 17 00:00:00 2001 From: guozhigq Date: Sun, 27 Oct 2024 16:15:50 +0800 Subject: [PATCH 09/15] opt: bangumi layout --- lib/common/pages_bottom_sheet.dart | 2 +- lib/pages/bangumi/introduction/view.dart | 127 ++++++++----------- lib/pages/bangumi/widgets/bangumi_panel.dart | 95 +++++++------- 3 files changed, 101 insertions(+), 123 deletions(-) diff --git a/lib/common/pages_bottom_sheet.dart b/lib/common/pages_bottom_sheet.dart index d7eea2ca..afc74bd2 100644 --- a/lib/common/pages_bottom_sheet.dart +++ b/lib/common/pages_bottom_sheet.dart @@ -430,7 +430,7 @@ class EpisodeGridItem extends StatelessWidget { decoration: BoxDecoration( color: isCurrentIndex ? colorScheme.primaryContainer.withOpacity(0.6) - : colorScheme.secondaryContainer.withOpacity(0.4), + : colorScheme.onInverseSurface.withOpacity(0.6), borderRadius: BorderRadius.circular(8), border: Border.all( color: isCurrentIndex diff --git a/lib/pages/bangumi/introduction/view.dart b/lib/pages/bangumi/introduction/view.dart index b90ef992..429b109a 100644 --- a/lib/pages/bangumi/introduction/view.dart +++ b/lib/pages/bangumi/introduction/view.dart @@ -239,88 +239,65 @@ class _BangumiInfoState extends State { Expanded( child: InkWell( onTap: () => showIntroDetail(), + borderRadius: BorderRadius.circular(8), child: SizedBox( height: 115 / 0.75, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - Row( - children: [ - Expanded( - child: Text( - widget.bangumiDetail!.title!, - style: const TextStyle( - fontSize: 16, - fontWeight: FontWeight.w500, + child: Padding( + padding: const EdgeInsets.fromLTRB(6, 4, 6, 6), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Expanded( + child: Text( + widget.bangumiDetail!.title!, + style: const TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + ), + maxLines: 2, + overflow: TextOverflow.ellipsis, ), - maxLines: 1, - overflow: TextOverflow.ellipsis, ), - ), - const SizedBox(width: 20), - Obx( - () => BangumiStatusWidget( - ctr: bangumiIntroController, - isFollowed: - bangumiIntroController.isFollowed.value, + const SizedBox(width: 20), + Obx( + () => BangumiStatusWidget( + ctr: bangumiIntroController, + isFollowed: + bangumiIntroController.isFollowed.value, + ), ), - ), - ], - ), - Row( - children: [ - StatView( - view: widget.bangumiDetail!.stat!['views'], - size: 'medium', - ), - const SizedBox(width: 6), - StatDanMu( - danmu: widget.bangumiDetail!.stat!['danmakus'], - size: 'medium', - ), - ], - ), - const SizedBox(height: 6), - Row( - children: [ - Text( - (widget.bangumiDetail!.areas!.isNotEmpty - ? widget.bangumiDetail!.areas!.first['name'] - : ''), - style: TextStyle( - fontSize: 12, - color: t.colorScheme.outline, - ), - ), - const SizedBox(width: 6), - Text( - widget.bangumiDetail!.publish!['pub_time_show'], - style: TextStyle( - fontSize: 12, - color: t.colorScheme.outline, - ), - ), - ], - ), - Text( - widget.bangumiDetail!.newEp!['desc'], - style: TextStyle( - fontSize: 12, - color: t.colorScheme.outline, + ], ), - ), - const Spacer(), - Text( - '简介:${widget.bangumiDetail!.evaluate!}', - maxLines: 3, - overflow: TextOverflow.ellipsis, - style: TextStyle( - fontSize: 13, - color: t.colorScheme.outline, + const SizedBox(height: 4), + Row( + children: [ + StatView( + view: widget.bangumiDetail!.stat!['views'], + size: 'medium', + ), + const SizedBox(width: 6), + StatDanMu( + danmu: widget.bangumiDetail!.stat!['danmakus'], + size: 'medium', + ), + ], ), - ), - ], + const SizedBox(height: 10), + Text( + '简介:${widget.bangumiDetail!.evaluate!}', + maxLines: 3, + overflow: TextOverflow.ellipsis, + style: TextStyle( + fontSize: 14, + color: t.colorScheme.outline, + ), + ), + ], + ), ), ), ), diff --git a/lib/pages/bangumi/widgets/bangumi_panel.dart b/lib/pages/bangumi/widgets/bangumi_panel.dart index 3cb9abc0..db29d8e2 100644 --- a/lib/pages/bangumi/widgets/bangumi_panel.dart +++ b/lib/pages/bangumi/widgets/bangumi_panel.dart @@ -175,59 +175,60 @@ class _BangumiPanelState extends State { return Container( width: 150, margin: const EdgeInsets.only(right: 10), - child: Material( + clipBehavior: Clip.antiAlias, + decoration: BoxDecoration( color: Theme.of(context).colorScheme.onInverseSurface, - borderRadius: BorderRadius.circular(6), - clipBehavior: Clip.hardEdge, - child: InkWell( - onTap: () => changeFucCall(page, i), - child: Padding( - padding: const EdgeInsets.symmetric( - vertical: 8, - horizontal: 10, - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - children: [ - if (isSelected) ...[ - Image.asset('assets/images/live.png', - color: primary, height: 12), - const SizedBox(width: 6) - ], + borderRadius: BorderRadius.circular(8), + ), + child: InkWell( + borderRadius: BorderRadius.circular(8), + onTap: () => changeFucCall(page, i), + child: Padding( + padding: const EdgeInsets.symmetric( + vertical: 8, + horizontal: 10, + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + if (isSelected) ...[ + Image.asset('assets/images/live.png', + color: primary, height: 12), + const SizedBox(width: 6) + ], + Text( + '第${i + 1}话', + style: TextStyle( + fontSize: 13, + color: isSelected ? primary : onSurface, + ), + ), + const SizedBox(width: 2), + if (page.badge != null) ...[ + const Spacer(), Text( - '第${i + 1}话', + page.badge!, style: TextStyle( - fontSize: 13, - color: isSelected ? primary : onSurface, + fontSize: 12, + color: primary, ), ), - const SizedBox(width: 2), - if (page.badge != null) ...[ - const Spacer(), - Text( - page.badge!, - style: TextStyle( - fontSize: 12, - color: primary, - ), - ), - ] - ], + ] + ], + ), + const SizedBox(height: 3), + Text( + page.longTitle!, + maxLines: 1, + style: TextStyle( + fontSize: 13, + color: isSelected ? primary : onSurface, ), - const SizedBox(height: 3), - Text( - page.longTitle!, - maxLines: 1, - style: TextStyle( - fontSize: 13, - color: isSelected ? primary : onSurface, - ), - overflow: TextOverflow.ellipsis, - ) - ], - ), + overflow: TextOverflow.ellipsis, + ) + ], ), ), ), From fbc1288defa9996b94563eaa491afe4de131e30c Mon Sep 17 00:00:00 2001 From: guozhigq Date: Sun, 27 Oct 2024 18:31:28 +0800 Subject: [PATCH 10/15] opt: bangumi progress --- lib/http/api.dart | 7 ++- lib/http/bangumi.dart | 28 +++++++++++- lib/models/bangumi/list.dart | 7 ++- lib/pages/bangumi/controller.dart | 4 +- .../bangumi/introduction/controller.dart | 43 +++++++------------ lib/pages/bangumi/view.dart | 11 +++-- lib/pages/bangumi/widgets/bangumu_card_v.dart | 1 + lib/utils/route_push.dart | 7 ++- 8 files changed, 66 insertions(+), 42 deletions(-) diff --git a/lib/http/api.dart b/lib/http/api.dart index 04983339..2bd83d69 100644 --- a/lib/http/api.dart +++ b/lib/http/api.dart @@ -301,10 +301,6 @@ class Api { static const String bangumiList = '/pgc/season/index/result?st=1&order=3&season_version=-1&spoken_language_type=-1&area=-1&is_finish=-1©right=-1&season_status=-1&season_month=-1&year=-1&style_id=-1&sort=0&season_type=1&pagesize=20&type=1'; - // 我的订阅 - static const String bangumiFollow = - '/x/space/bangumi/follow/list?type=1&follow_status=0&pn=1&ps=15&ts=1691544359969'; - // 黑名单 static const String blackLst = '/x/relation/blacks'; @@ -607,4 +603,7 @@ class Api { /// 更新追番状态 static const String updateBangumiStatus = '/pgc/web/follow/status/update'; + + /// 番剧点赞投币收藏状态 + static const String bangumiActionStatus = '/pgc/season/episode/community'; } diff --git a/lib/http/bangumi.dart b/lib/http/bangumi.dart index e9ccce96..d0c052d6 100644 --- a/lib/http/bangumi.dart +++ b/lib/http/bangumi.dart @@ -21,8 +21,19 @@ class BangumiHttp { } } - static Future bangumiFollow({int? mid}) async { - var res = await Request().get(Api.bangumiFollow, data: {'vmid': mid}); + static Future getRecentBangumi({ + int? mid, + int type = 1, + int pn = 1, + int ps = 20, + }) async { + var res = await Request().get(Api.getRecentBangumiApi, data: { + 'vmid': mid, + 'type': type, + 'follow_status': 0, + 'pn': pn, + 'ps': ps, + }); if (res.data['code'] == 0) { return { 'status': true, @@ -81,4 +92,17 @@ class BangumiHttp { }; } } + + // 获取番剧点赞投币收藏状态 + static Future bangumiActionStatus({required int epId}) async { + var res = await Request().get( + Api.bangumiActionStatus, + data: {'ep_id': epId}, + ); + if (res.data['code'] == 0) { + return {'status': true, 'data': res.data['data']}; + } else { + return {'status': false, 'data': [], 'msg': res.data['message']}; + } + } } diff --git a/lib/models/bangumi/list.dart b/lib/models/bangumi/list.dart index fe71bb61..df20fa3b 100644 --- a/lib/models/bangumi/list.dart +++ b/lib/models/bangumi/list.dart @@ -47,6 +47,7 @@ class BangumiListItemModel { this.title, this.titleIcon, this.progress, + this.progressIndex, }); String? badge; @@ -66,8 +67,8 @@ class BangumiListItemModel { String? subTitle; String? title; String? titleIcon; - String? progress; + int? progressIndex; BangumiListItemModel.fromJson(Map json) { badge = json['badge'] == '' ? null : json['badge']; @@ -87,7 +88,9 @@ class BangumiListItemModel { subTitle = json['sub_title']; title = json['title']; titleIcon = json['title_icon']; - progress = json['progress']; + progressIndex = int.parse( + RegExp(r'第(\d+)话').firstMatch(json['progress'] ?? '第1话')?.group(1) ?? + '0'); } } diff --git a/lib/pages/bangumi/controller.dart b/lib/pages/bangumi/controller.dart index e5748d6c..29dd15d1 100644 --- a/lib/pages/bangumi/controller.dart +++ b/lib/pages/bangumi/controller.dart @@ -9,6 +9,7 @@ class BangumiController extends GetxController { final ScrollController scrollController = ScrollController(); RxList bangumiList = [].obs; RxList bangumiFollowList = [].obs; + RxInt total = 0.obs; int _currentPage = 1; bool isLoadingMore = true; Box userInfoCache = GStrorage.userInfo; @@ -54,9 +55,10 @@ class BangumiController extends GetxController { if (userInfo == null) { return; } - var result = await BangumiHttp.bangumiFollow(mid: userInfo.mid); + var result = await BangumiHttp.getRecentBangumi(mid: userInfo.mid); if (result['status']) { bangumiFollowList.value = result['data'].list; + total.value = result['data'].total; } else {} return result; } diff --git a/lib/pages/bangumi/introduction/controller.dart b/lib/pages/bangumi/introduction/controller.dart index f2d7807e..dc173a57 100644 --- a/lib/pages/bangumi/introduction/controller.dart +++ b/lib/pages/bangumi/introduction/controller.dart @@ -79,12 +79,8 @@ class BangumiIntroController extends GetxController { // 获取番剧简介&选集 Future queryBangumiIntro() async { if (userLogin) { - // 获取点赞状态 - queryHasLikeVideo(); - // 获取投币状态 - queryHasCoinVideo(); - // 获取收藏状态 - queryHasFavVideo(); + // 获取点赞投币收藏状态 + bangumiActionStatus(); } var result = await SearchHttp.bangumiInfo(seasonId: seasonId, epId: epId); if (result['status']) { @@ -94,26 +90,15 @@ class BangumiIntroController extends GetxController { return result; } - // 获取点赞状态 - Future queryHasLikeVideo() async { - var result = await VideoHttp.hasLikeVideo(bvid: bvid); - // data num 被点赞标志 0:未点赞 1:已点赞 - hasLike.value = result["data"] == 1 ? true : false; - } - - // 获取投币状态 - Future queryHasCoinVideo() async { - var result = await VideoHttp.hasCoinVideo(bvid: bvid); - hasCoin.value = result["data"]['multiply'] == 0 ? false : true; - } - - // 获取收藏状态 - Future queryHasFavVideo() async { - var result = await VideoHttp.hasFavVideo(aid: IdUtils.bv2av(bvid)); + // 获取番剧点赞投币收藏状态 + Future bangumiActionStatus() async { + var result = await BangumiHttp.bangumiActionStatus(epId: epId!); if (result['status']) { - hasFav.value = result["data"]['favoured']; + hasLike.value = result['data']['like'] == 1; + hasCoin.value = result['data']['coin_number'] != 0; + hasFav.value = result['data']['favorite'] == 1; } else { - hasFav.value = false; + SmartDialog.showToast(result['msg']); } } @@ -121,7 +106,7 @@ class BangumiIntroController extends GetxController { Future actionLikeVideo() async { var result = await VideoHttp.likeVideo(bvid: bvid, type: !hasLike.value); if (result['status']) { - SmartDialog.showToast(!hasLike.value ? '点赞成功 👍' : '取消赞'); + SmartDialog.showToast(!hasLike.value ? '点赞成功' : '取消赞'); hasLike.value = !hasLike.value; bangumiDetail.value.stat!['likes'] = bangumiDetail.value.stat!['likes'] + (!hasLike.value ? 1 : -1); @@ -158,7 +143,7 @@ class BangumiIntroController extends GetxController { var res = await VideoHttp.coinVideo( bvid: bvid, multiply: _tempThemeValue); if (res['status']) { - SmartDialog.showToast('投币成功 👏'); + SmartDialog.showToast('投币成功'); hasCoin.value = true; bangumiDetail.value.stat!['coins'] = bangumiDetail.value.stat!['coins'] + @@ -196,9 +181,11 @@ class BangumiIntroController extends GetxController { addMediaIdsNew = []; delMediaIdsNew = []; // 重新获取收藏状态 - queryHasFavVideo(); - SmartDialog.showToast('✅ 操作成功'); + bangumiActionStatus(); + SmartDialog.showToast('操作成功'); Get.back(); + } else { + SmartDialog.showToast(result['msg']); } } diff --git a/lib/pages/bangumi/view.dart b/lib/pages/bangumi/view.dart index 4092943b..f1f8d279 100644 --- a/lib/pages/bangumi/view.dart +++ b/lib/pages/bangumi/view.dart @@ -76,9 +76,14 @@ class _BangumiPageState extends State child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Text( - '最近追番', - style: Theme.of(context).textTheme.titleMedium, + Obx( + () => 0 != _bangumidController.total.value + ? Text( + '我的追番(${_bangumidController.total.value})', + style: + Theme.of(context).textTheme.titleMedium, + ) + : const SizedBox(), ), IconButton( onPressed: () { diff --git a/lib/pages/bangumi/widgets/bangumu_card_v.dart b/lib/pages/bangumi/widgets/bangumu_card_v.dart index 10d95a1c..19aa4d88 100644 --- a/lib/pages/bangumi/widgets/bangumu_card_v.dart +++ b/lib/pages/bangumi/widgets/bangumu_card_v.dart @@ -25,6 +25,7 @@ class BangumiCardV extends StatelessWidget { RoutePush.bangumiPush( bangumiItem.seasonId, null, + progressIndex: bangumiItem.progressIndex, heroTag: heroTag, ); }, diff --git a/lib/utils/route_push.dart b/lib/utils/route_push.dart index e639327d..9254da2a 100644 --- a/lib/utils/route_push.dart +++ b/lib/utils/route_push.dart @@ -8,7 +8,7 @@ import 'package:pilipala/utils/utils.dart'; class RoutePush { // 番剧跳转 static Future bangumiPush(int? seasonId, int? epId, - {String? heroTag}) async { + {String? heroTag, int? progressIndex}) async { SmartDialog.showLoading(msg: '获取中...'); try { var result = await SearchHttp.bangumiInfo(seasonId: seasonId, epId: epId); @@ -19,7 +19,10 @@ class RoutePush { return; } final BangumiInfoModel bangumiDetail = result['data']; - final EpisodeItem episode = bangumiDetail.episodes!.first; + EpisodeItem episode = bangumiDetail.episodes!.first; + if (progressIndex != null && progressIndex >= 1) { + episode = bangumiDetail.episodes![progressIndex - 1]; + } final int epId = episode.id!; final int cid = episode.cid!; final String bvid = episode.bvid!; From ac90e14665e46b793394b6b16e9885eb98e11c4e Mon Sep 17 00:00:00 2001 From: guozhigq Date: Sun, 27 Oct 2024 21:28:56 +0800 Subject: [PATCH 11/15] fix: repeated reply --- lib/pages/dynamics/detail/controller.dart | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/pages/dynamics/detail/controller.dart b/lib/pages/dynamics/detail/controller.dart index f2e990cd..7ca55c59 100644 --- a/lib/pages/dynamics/detail/controller.dart +++ b/lib/pages/dynamics/detail/controller.dart @@ -48,8 +48,17 @@ class DynamicDetailController extends GetxController { } Future queryReplyList({reqType = 'init'}) async { + if (isLoadingMore) { + return; + } + isLoadingMore = true; if (reqType == 'init') { - nextOffset = ""; + nextOffset = ''; + noMore.value = ''; + } + if (noMore.value == '没有更多了') { + isLoadingMore = false; + return; } var res = await ReplyHttp.replyList( oid: oid!, From 3e630334ca13680249450a0d93e1b8d330d72942 Mon Sep 17 00:00:00 2001 From: guozhigq Date: Sun, 27 Oct 2024 23:46:33 +0800 Subject: [PATCH 12/15] =?UTF-8?q?fix=EF=BC=9A=E4=B8=93=E6=A0=8F=E5=9B=BE?= =?UTF-8?q?=E6=96=87=E6=B8=B2=E6=9F=93=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/pages/member_article/controller.dart | 2 +- lib/pages/member_article/view.dart | 14 ++++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/lib/pages/member_article/controller.dart b/lib/pages/member_article/controller.dart index d79fb4a6..936dd9da 100644 --- a/lib/pages/member_article/controller.dart +++ b/lib/pages/member_article/controller.dart @@ -20,7 +20,7 @@ class MemberArticleController extends GetxController { } Future getMemberArticle(type) async { - if (isLoading.value) { + if (isLoading.value || !hasMore) { return; } isLoading.value = true; diff --git a/lib/pages/member_article/view.dart b/lib/pages/member_article/view.dart index 67cb8b96..bc7d4087 100644 --- a/lib/pages/member_article/view.dart +++ b/lib/pages/member_article/view.dart @@ -113,12 +113,14 @@ class _MemberArticlePageState extends State { 'articleType': 'opus', }); }, - leading: NetworkImgLayer( - width: 50, - height: 50, - type: 'emote', - src: item?.cover?['url'] ?? '', - ), + leading: item?.cover != null + ? NetworkImgLayer( + width: 50, + height: 50, + type: 'emote', + src: item?.cover?['url'] ?? '', + ) + : const SizedBox(), title: Text( item.content, maxLines: 2, From c0190a526ffad775abcaa8c99a0a57da8eef2ff8 Mon Sep 17 00:00:00 2001 From: guozhigq Date: Mon, 28 Oct 2024 23:58:58 +0800 Subject: [PATCH 13/15] fix: msg page layout --- lib/models/msg/like.dart | 2 +- lib/models/msg/session.dart | 5 ++-- lib/pages/message/like/view.dart | 45 ++++++++++++++++--------------- lib/pages/message/reply/view.dart | 39 ++++++++++++++------------- lib/pages/whisper/view.dart | 3 ++- 5 files changed, 49 insertions(+), 45 deletions(-) diff --git a/lib/models/msg/like.dart b/lib/models/msg/like.dart index b279131b..25d6f3de 100644 --- a/lib/models/msg/like.dart +++ b/lib/models/msg/like.dart @@ -39,7 +39,7 @@ class Total { List? items; factory Total.fromJson(Map json) => Total( - cursor: Cursor.fromJson(json['cursor']), + cursor: json['cursor'] != null ? Cursor.fromJson(json['cursor']) : null, items: json["items"] == null ? [] : json["items"].map((e) { diff --git a/lib/models/msg/session.dart b/lib/models/msg/session.dart index b6c1b6a6..7b1aee6b 100644 --- a/lib/models/msg/session.dart +++ b/lib/models/msg/session.dart @@ -13,8 +13,9 @@ class SessionDataModel { SessionDataModel.fromJson(Map json) { sessionList = json['session_list'] - ?.map((e) => SessionList.fromJson(e)) - .toList(); + ?.map((e) => SessionList.fromJson(e)) + .toList() ?? + []; hasMore = json['has_more']; } } diff --git a/lib/pages/message/like/view.dart b/lib/pages/message/like/view.dart index 6a7ba8a4..c29a7cc8 100644 --- a/lib/pages/message/like/view.dart +++ b/lib/pages/message/like/view.dart @@ -3,6 +3,7 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:pilipala/common/widgets/http_error.dart'; import 'package:pilipala/common/widgets/network_img_layer.dart'; +import 'package:pilipala/common/widgets/no_data.dart'; import 'package:pilipala/models/msg/like.dart'; import 'package:pilipala/utils/utils.dart'; import '../utils/index.dart'; @@ -57,34 +58,34 @@ class _MessageLikePageState extends State { future: _futureBuilderFuture, builder: (BuildContext context, AsyncSnapshot snapshot) { if (snapshot.connectionState == ConnectionState.done) { - if (snapshot.data == null) { - return const SizedBox(); - } - if (snapshot.data['status']) { + Map? data = snapshot.data; + if (data != null && data['status']) { final likeItems = _messageLikeCtr.likeItems; return Obx( - () => ListView.separated( - controller: scrollController, - itemBuilder: (context, index) => LikeItem( - item: likeItems[index], - index: index, - messageLikeCtr: _messageLikeCtr, - ), - itemCount: likeItems.length, - separatorBuilder: (BuildContext context, int index) { - return Divider( - indent: 66, - endIndent: 14, - height: 1, - color: Colors.grey.withOpacity(0.1), - ); - }, - ), + () => likeItems.isEmpty + ? const CustomScrollView(slivers: [NoData()]) + : ListView.separated( + controller: scrollController, + itemBuilder: (context, index) => LikeItem( + item: likeItems[index], + index: index, + messageLikeCtr: _messageLikeCtr, + ), + itemCount: likeItems.length, + separatorBuilder: (BuildContext context, int index) { + return Divider( + indent: 66, + endIndent: 14, + height: 1, + color: Colors.grey.withOpacity(0.1), + ); + }, + ), ); } else { // 请求错误 return HttpError( - errMsg: snapshot.data['msg'], + errMsg: data?['msg'] ?? '请求异常', fn: () { setState(() { _futureBuilderFuture = _messageLikeCtr.queryMessageLike(); diff --git a/lib/pages/message/reply/view.dart b/lib/pages/message/reply/view.dart index 63a4de4a..325b494f 100644 --- a/lib/pages/message/reply/view.dart +++ b/lib/pages/message/reply/view.dart @@ -4,6 +4,7 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:pilipala/common/widgets/http_error.dart'; import 'package:pilipala/common/widgets/network_img_layer.dart'; +import 'package:pilipala/common/widgets/no_data.dart'; import 'package:pilipala/models/msg/reply.dart'; import 'package:pilipala/pages/message/utils/index.dart'; import 'package:pilipala/utils/utils.dart'; @@ -58,31 +59,31 @@ class _MessageReplyPageState extends State { future: _futureBuilderFuture, builder: (BuildContext context, AsyncSnapshot snapshot) { if (snapshot.connectionState == ConnectionState.done) { - if (snapshot.data == null) { - return const SizedBox(); - } - if (snapshot.data['status']) { + Map? data = snapshot.data; + if (data != null && data['status']) { final replyItems = _messageReplyCtr.replyItems; return Obx( - () => ListView.separated( - controller: scrollController, - itemBuilder: (context, index) => - ReplyItem(item: replyItems[index]), - itemCount: replyItems.length, - separatorBuilder: (BuildContext context, int index) { - return Divider( - indent: 66, - endIndent: 14, - height: 1, - color: Colors.grey.withOpacity(0.1), - ); - }, - ), + () => replyItems.isEmpty + ? const CustomScrollView(slivers: [NoData()]) + : ListView.separated( + controller: scrollController, + itemBuilder: (context, index) => + ReplyItem(item: replyItems[index]), + itemCount: replyItems.length, + separatorBuilder: (BuildContext context, int index) { + return Divider( + indent: 66, + endIndent: 14, + height: 1, + color: Colors.grey.withOpacity(0.1), + ); + }, + ), ); } else { // 请求错误 return HttpError( - errMsg: snapshot.data['msg'], + errMsg: data?['msg'] ?? '请求异常', fn: () { setState(() { _futureBuilderFuture = diff --git a/lib/pages/whisper/view.dart b/lib/pages/whisper/view.dart index 8e61bab3..e06a836d 100644 --- a/lib/pages/whisper/view.dart +++ b/lib/pages/whisper/view.dart @@ -5,6 +5,7 @@ import 'package:get/get.dart'; import 'package:pilipala/common/constants.dart'; import 'package:pilipala/common/skeleton/skeleton.dart'; import 'package:pilipala/common/widgets/network_img_layer.dart'; +import 'package:pilipala/common/widgets/no_data.dart'; import 'package:pilipala/utils/utils.dart'; import 'controller.dart'; @@ -126,7 +127,7 @@ class _WhisperPageState extends State { RxList sessionList = _whisperController.sessionList; return Obx( () => sessionList.isEmpty - ? const SizedBox() + ? const CustomScrollView(slivers: [NoData()]) : ListView.separated( itemCount: sessionList.length, shrinkWrap: true, From 26f3492ad25eda32b329a771df999044032de466 Mon Sep 17 00:00:00 2001 From: guozhigq Date: Tue, 29 Oct 2024 09:47:11 +0800 Subject: [PATCH 14/15] fix: customer service message --- lib/http/msg.dart | 3 ++- lib/pages/whisper/controller.dart | 29 ++++++++++++++++++++++++++--- lib/pages/whisper/view.dart | 12 ++++++++++-- 3 files changed, 38 insertions(+), 6 deletions(-) diff --git a/lib/http/msg.dart b/lib/http/msg.dart index 5568e226..ebcb0895 100644 --- a/lib/http/msg.dart +++ b/lib/http/msg.dart @@ -1,5 +1,6 @@ import 'dart:convert'; import 'dart:math'; +import 'package:flutter/material.dart'; import 'package:pilipala/models/msg/like.dart'; import 'package:pilipala/models/msg/reply.dart'; import 'package:pilipala/models/msg/system.dart'; @@ -63,7 +64,7 @@ class MsgHttp { .toList(), }; } catch (err) { - print('err🔟: $err'); + debugPrint('err: $err'); } } else { return { diff --git a/lib/pages/whisper/controller.dart b/lib/pages/whisper/controller.dart index 749a3482..b4deb014 100644 --- a/lib/pages/whisper/controller.dart +++ b/lib/pages/whisper/controller.dart @@ -45,7 +45,9 @@ class WhisperController extends GetxController { if (isLoading) return; var res = await MsgHttp.sessionList( endTs: type == 'onLoad' ? sessionList.last.sessionTs : null); - if (res['data'].sessionList != null && res['data'].sessionList.isNotEmpty) { + if (res['status'] && + res['data'].sessionList != null && + res['data'].sessionList.isNotEmpty) { await queryAccountList(res['data'].sessionList); // 将 accountList 转换为 Map 结构 Map accountMap = {}; @@ -67,8 +69,6 @@ class WhisperController extends GetxController { ); } } - } - if (res['status'] && res['data'].sessionList != null) { if (type == 'onLoad') { sessionList.addAll(res['data'].sessionList); } else { @@ -81,10 +81,33 @@ class WhisperController extends GetxController { Future queryAccountList(sessionList) async { List midsList = sessionList.map((e) => e.talkerId!).toList(); + var index = midsList.indexOf(0); + AccountListModel? accountInfo; + if (index != -1) { + accountInfo = AccountListModel( + mid: 0, + name: '客服消息', + face: + 'https://i0.hdslb.com/bfs/activity-plat/static/20230809/f87fc7ea98282a4dd48ec7743044b0bf/OWdoP9ZXAX.png', + ); + } + if (midsList.length == 1 && index != -1) { + accountList.add(accountInfo!); + return; + } + var res = await MsgHttp.accountList(midsList.join(',')); if (res['status']) { accountList.value = res['data']; + if (accountInfo != null) { + if (accountList.isNotEmpty) { + accountList.insert(index, accountInfo); + } else { + accountList.add(accountInfo); + } + } } + return res; } diff --git a/lib/pages/whisper/view.dart b/lib/pages/whisper/view.dart index e06a836d..4780b908 100644 --- a/lib/pages/whisper/view.dart +++ b/lib/pages/whisper/view.dart @@ -4,6 +4,7 @@ import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:get/get.dart'; import 'package:pilipala/common/constants.dart'; import 'package:pilipala/common/skeleton/skeleton.dart'; +import 'package:pilipala/common/widgets/http_error.dart'; import 'package:pilipala/common/widgets/network_img_layer.dart'; import 'package:pilipala/common/widgets/no_data.dart'; import 'package:pilipala/utils/utils.dart'; @@ -151,8 +152,15 @@ class _WhisperPageState extends State { ); } else { // 请求错误 - return Center( - child: Text(data?['msg'] ?? '请求异常'), + return HttpError( + errMsg: data?['msg'] ?? '请求异常', + fn: () { + setState(() { + _futureBuilderFuture = + _whisperController.querySessionList('init'); + }); + }, + isInSliver: false, ); } } else { From 7a1f3c95a9012802b7230018a0f17b1ea80b904f Mon Sep 17 00:00:00 2001 From: guozhigq Date: Tue, 29 Oct 2024 23:39:56 +0800 Subject: [PATCH 15/15] fix: text overflow --- lib/pages/home/view.dart | 15 +++++++++------ lib/pages/subscription_detail/view.dart | 13 +++++++++---- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/lib/pages/home/view.dart b/lib/pages/home/view.dart index 2c32aa0d..97378eaf 100644 --- a/lib/pages/home/view.dart +++ b/lib/pages/home/view.dart @@ -395,14 +395,17 @@ class SearchBar extends StatelessWidget { color: colorScheme.onSecondaryContainer, ), const SizedBox(width: 10), - Obx( - () => Text( - ctr!.defaultSearch.value, - maxLines: 1, - overflow: TextOverflow.ellipsis, - style: TextStyle(color: colorScheme.outline), + Expanded( + child: Obx( + () => Text( + ctr!.defaultSearch.value, + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: TextStyle(color: colorScheme.outline), + ), ), ), + const SizedBox(width: 10), ], ), ), diff --git a/lib/pages/subscription_detail/view.dart b/lib/pages/subscription_detail/view.dart index b41754d9..4bf93109 100644 --- a/lib/pages/subscription_detail/view.dart +++ b/lib/pages/subscription_detail/view.dart @@ -80,16 +80,21 @@ class _SubDetailPageState extends State { Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( - _subDetailController.item.title!, - style: Theme.of(context).textTheme.titleMedium, + SizedBox( + width: Get.size.width - 100, + child: Text( + _subDetailController.item.title!, + overflow: TextOverflow.ellipsis, + maxLines: 1, + style: Theme.of(context).textTheme.titleMedium, + ), ), Text( '共${_subDetailController.item.mediaCount!}条视频', style: Theme.of(context).textTheme.labelMedium, ) ], - ) + ), ], ), );