diff --git a/lib/common/widgets/video_card_v.dart b/lib/common/widgets/video_card_v.dart index 4ed360655..6754dfd69 100644 --- a/lib/common/widgets/video_card_v.dart +++ b/lib/common/widgets/video_card_v.dart @@ -35,44 +35,7 @@ class VideoCardV extends StatelessWidget { String goto = videoItem.goto; switch (goto) { case 'bangumi': - // if (videoItem.bangumiBadge == '电影') { - // SmartDialog.showToast('暂不支持电影观看'); - // return; - // } Utils.viewBangumi(epId: videoItem.param); - // SmartDialog.showLoading(msg: '资源获取中'); - // var result = await SearchHttp.bangumiInfo(seasonId: null, epId: epId); - // SmartDialog.dismiss(); - // if (result['status']) { - // var bangumiDetail = result['data']; - // EpisodeItem episode = result['data'].episodes.first; - // int? epId = result['data'].userStatus?.progress?.lastEpId; - // if (epId == null) { - // epId = episode.epId; - // } else { - // for (var item in result['data'].episodes) { - // if (item.epId == epId) { - // episode = item; - // break; - // } - // } - // } - // String bvid = episode.bvid!; - // int cid = episode.cid!; - // String pic = episode.cover!; - // String seasonId = bangumiDetail.seasonId; - // dynamic heroTag = Utils.makeHeroTag(cid); - // Get.toNamed( - // '/video?bvid=$bvid&cid=$cid&seasonId=$seasonId&epId=$epId', - // arguments: { - // 'pic': pic, - // 'heroTag': heroTag, - // 'videoType': SearchType.media_bangumi, - // }, - // ); - // } else { - // SmartDialog.showToast(result['msg']); - // } break; case 'av': String bvid = videoItem.bvid ?? IdUtils.av2bv(videoItem.aid); diff --git a/lib/common/widgets/video_card_v_member_home.dart b/lib/common/widgets/video_card_v_member_home.dart index 88a943b87..0db74cd9c 100644 --- a/lib/common/widgets/video_card_v_member_home.dart +++ b/lib/common/widgets/video_card_v_member_home.dart @@ -21,47 +21,8 @@ class VideoCardVMemberHome extends StatelessWidget { String goto = videoItem.goto ?? ''; switch (goto) { case 'bangumi': - // if (videoItem.bangumiBadge == '电影') { - // SmartDialog.showToast('暂不支持电影观看'); - // return; - // } - // int epId = videoItem.param; Utils.viewBangumi(epId: videoItem.param); - - // SmartDialog.showLoading(msg: '资源获取中'); - // var result = await SearchHttp.bangumiInfo(seasonId: null, epId: epId); - // SmartDialog.dismiss(); - // if (result['status']) { - // var bangumiDetail = result['data']; - // EpisodeItem episode = result['data'].episodes.first; - // int? epId = result['data'].userStatus?.progress?.lastEpId; - // if (epId == null) { - // epId = episode.epId; - // } else { - // for (var item in result['data'].episodes) { - // if (item.epId == epId) { - // episode = item; - // break; - // } - // } - // } - // String bvid = episode.bvid!; - // int cid = episode.cid!; - // String pic = episode.cover!; - // String seasonId = bangumiDetail.seasonId; - // dynamic heroTag = Utils.makeHeroTag(cid); - // Get.toNamed( - // '/video?bvid=$bvid&cid=$cid&seasonId=$seasonId&epId=$epId', - // arguments: { - // 'pic': pic, - // 'heroTag': heroTag, - // 'videoType': SearchType.media_bangumi, - // }, - // ); - // } else { - // SmartDialog.showToast(result['msg']); - // } - // break; + break; case 'av': if (videoItem.isPgc == true && videoItem.uri?.isNotEmpty == true) { if (Utils.viewPgcFromUri(videoItem.uri!)) { diff --git a/lib/http/member.dart b/lib/http/member.dart index a09a14115..66bdf6e06 100644 --- a/lib/http/member.dart +++ b/lib/http/member.dart @@ -598,7 +598,7 @@ class MemberHttp { } // 最近投币 - static Future getRecentCoinVideo({required int mid}) async { + static Future getRecentCoinVideo({required int mid}) async { Map params = await WbiSign().makSign({ 'mid': mid, 'gaia_source': 'main_web', @@ -615,23 +615,16 @@ class MemberHttp { }, ); if (res.data['code'] == 0) { - return { - 'status': true, - 'data': res.data['data'] - .map((e) => MemberCoinsDataModel.fromJson(e)) - .toList(), - }; + return LoadingState.success(res.data['data'] + .map((e) => MemberCoinsDataModel.fromJson(e)) + .toList()); } else { - return { - 'status': false, - 'data': [], - 'msg': res.data['message'], - }; + return LoadingState.error(res.data['message']); } } // 最近点赞 - static Future getRecentLikeVideo({required int mid}) async { + static Future getRecentLikeVideo({required int mid}) async { Map params = await WbiSign().makSign({ 'mid': mid, 'gaia_source': 'main_web', @@ -648,16 +641,11 @@ class MemberHttp { }, ); if (res.data['code'] == 0) { - return { - 'status': true, - 'data': MemberSeasonsDataModel.fromJson(res.data['data']['items_lists']) - }; + return LoadingState.success(res.data['data']['list'] + .map((e) => MemberCoinsDataModel.fromJson(e)) + .toList()); } else { - return { - 'status': false, - 'data': [], - 'msg': res.data['message'], - }; + return LoadingState.error(res.data['message']); } } diff --git a/lib/pages/member/controller.dart b/lib/pages/member/controller.dart index 40ae8b16d..21835f912 100644 --- a/lib/pages/member/controller.dart +++ b/lib/pages/member/controller.dart @@ -254,10 +254,10 @@ class MemberController extends GetxController { // 请求投币视频 Future getRecentCoinVideo() async { - if (userInfo == null) return; - var res = await MemberHttp.getRecentCoinVideo(mid: mid!); - recentCoinsList.value = res['data']; - return res; + // if (userInfo == null) return; + // var res = await MemberHttp.getRecentCoinVideo(mid: mid!); + // recentCoinsList.value = res['data']; + // return res; } // 跳转查看动态 diff --git a/lib/pages/member/new/content/member_home/member_home.dart b/lib/pages/member/new/content/member_home/member_home.dart index aab8d2080..f9f99e28a 100644 --- a/lib/pages/member/new/content/member_home/member_home.dart +++ b/lib/pages/member/new/content/member_home/member_home.dart @@ -10,6 +10,8 @@ import 'package:PiliPlus/models/space/item.dart'; import 'package:PiliPlus/pages/bangumi/widgets/bangumi_card_v_member_home.dart'; import 'package:PiliPlus/pages/member/new/content/member_contribute/member_contribute_ctr.dart'; import 'package:PiliPlus/pages/member/new/controller.dart'; +import 'package:PiliPlus/pages/member_coin/index.dart'; +import 'package:PiliPlus/pages/member_like/index.dart'; import 'package:PiliPlus/utils/grid.dart'; import 'package:flutter/material.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; @@ -271,6 +273,21 @@ class _MemberHomeState extends State } _ctr.tabController?.animateTo(index); } else { + if (param == 'coinArchive') { + Get.to(MemberCoinPage( + mid: _ctr.mid, + name: _ctr.username, + )); + return; + } + + if (param == 'likeArchive') { + Get.to(MemberLikePage( + mid: _ctr.mid, + name: _ctr.username, + )); + return; + } // TODO SmartDialog.showToast('view $param'); } diff --git a/lib/pages/member/new/controller.dart b/lib/pages/member/new/controller.dart index be1f572cd..455744127 100644 --- a/lib/pages/member/new/controller.dart +++ b/lib/pages/member/new/controller.dart @@ -23,7 +23,7 @@ extension MemberTabTypeExt on MemberTabType { class MemberControllerNew extends CommonController with GetTickerProviderStateMixin { MemberControllerNew({required this.mid}); - int? mid; + int mid; RxDouble scrollRatio = 0.0.obs; String? username; int? ownerMid; @@ -154,7 +154,7 @@ class MemberControllerNew extends CommonController void _onBlock() async { dynamic res = await VideoHttp.relationMod( - mid: mid ?? -1, + mid: mid, act: relation.value != -1 ? 5 : 6, reSrc: 11, ); diff --git a/lib/pages/member/new/member_page.dart b/lib/pages/member/new/member_page.dart index 54d6d91c0..1f134161d 100644 --- a/lib/pages/member/new/member_page.dart +++ b/lib/pages/member/new/member_page.dart @@ -26,7 +26,7 @@ class MemberPageNew extends StatefulWidget { class _MemberPageNewState extends State with TickerProviderStateMixin { - int? _mid; + late final int _mid; late final String _heroTag; late final MemberControllerNew _userController; final _key = GlobalKey(); @@ -161,16 +161,16 @@ class _MemberPageNewState extends State () => MemberContribute( heroTag: _heroTag, initialIndex: _userController.contributeInitialIndex.value, - mid: _mid ?? -1, + mid: _mid, ), ), 'bangumi' => MemberBangumi( heroTag: _heroTag, - mid: _mid ?? -1, + mid: _mid, ), 'favorite' => MemberFavorite( heroTag: _heroTag, - mid: _mid ?? -1, + mid: _mid, ), _ => Center(child: Text(item.title ?? '')), }; diff --git a/lib/pages/member_coin/controller.dart b/lib/pages/member_coin/controller.dart index dc3f5d8f6..d0c9878be 100644 --- a/lib/pages/member_coin/controller.dart +++ b/lib/pages/member_coin/controller.dart @@ -1,3 +1,18 @@ -import 'package:get/get.dart'; +import 'package:PiliPlus/http/loading_state.dart'; +import 'package:PiliPlus/http/member.dart'; +import 'package:PiliPlus/pages/common/common_controller.dart'; -class MemberCoinController extends GetxController {} +class MemberCoinController extends CommonController { + final dynamic mid; + MemberCoinController({this.mid}); + + @override + void onInit() { + super.onInit(); + queryData(); + } + + @override + Future customGetData() => + MemberHttp.getRecentCoinVideo(mid: mid); +} diff --git a/lib/pages/member_coin/view.dart b/lib/pages/member_coin/view.dart index f74880a56..615eaa994 100644 --- a/lib/pages/member_coin/view.dart +++ b/lib/pages/member_coin/view.dart @@ -1,15 +1,75 @@ +import 'package:PiliPlus/common/constants.dart'; +import 'package:PiliPlus/common/widgets/loading_widget.dart'; +import 'package:PiliPlus/http/loading_state.dart'; +import 'package:PiliPlus/pages/member_coin/controller.dart'; +import 'package:PiliPlus/pages/member_coin/widgets/item.dart'; +import 'package:PiliPlus/utils/grid.dart'; +import 'package:PiliPlus/utils/storage.dart'; +import 'package:PiliPlus/utils/utils.dart'; import 'package:flutter/material.dart'; +import 'package:get/get.dart'; class MemberCoinPage extends StatefulWidget { - const MemberCoinPage({super.key}); + const MemberCoinPage({ + super.key, + required this.mid, + this.name, + }); + + final dynamic mid; + final String? name; @override State createState() => _MemberCoinPageState(); } class _MemberCoinPageState extends State { + late final _ownerMid = GStorage.ownerMid; + + late final _ctr = Get.put( + MemberCoinController(mid: widget.mid), + tag: Utils.makeHeroTag(widget.mid), + ); + @override Widget build(BuildContext context) { - return Scaffold(); + return Scaffold( + appBar: AppBar( + title: Text('${widget.mid == _ownerMid ? '我' : '${widget.name}'}的最近投币'), + ), + body: Obx(() => _buildBody(_ctr.loadingState.value)), + ); + } + + Widget _buildBody(LoadingState loadingState) { + return switch (loadingState) { + Loading() => loadingWidget, + Success() => (loadingState.response as List?)?.isNotEmpty == true + ? GridView.builder( + padding: EdgeInsets.only( + top: StyleString.safeSpace - 5, + left: StyleString.safeSpace, + right: StyleString.safeSpace, + bottom: MediaQuery.paddingOf(context).bottom + 80, + ), + gridDelegate: SliverGridDelegateWithExtentAndRatio( + mainAxisSpacing: StyleString.cardSpace, + crossAxisSpacing: StyleString.cardSpace, + maxCrossAxisExtent: Grid.smallCardWidth, + childAspectRatio: StyleString.aspectRatio, + mainAxisExtent: MediaQuery.textScalerOf(context).scale(75), + ), + itemCount: loadingState.response.length, + itemBuilder: (context, index) { + return MemberCoinsItem(coinItem: loadingState.response[index]); + }, + ) + : scrollErrorWidget(callback: _ctr.onReload), + Error() => scrollErrorWidget( + errMsg: loadingState.errMsg, + callback: _ctr.onReload, + ), + LoadingState() => throw UnimplementedError(), + }; } } diff --git a/lib/pages/member_coin/widgets/item.dart b/lib/pages/member_coin/widgets/item.dart index 68c2c35c5..dc8112913 100644 --- a/lib/pages/member_coin/widgets/item.dart +++ b/lib/pages/member_coin/widgets/item.dart @@ -1,3 +1,4 @@ +import 'package:PiliPlus/common/widgets/image_save.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:PiliPlus/common/constants.dart'; @@ -19,7 +20,6 @@ class MemberCoinsItem extends StatelessWidget { @override Widget build(BuildContext context) { return Card( - elevation: 0, clipBehavior: Clip.hardEdge, margin: EdgeInsets.zero, child: InkWell( @@ -34,7 +34,13 @@ class MemberCoinsItem extends StatelessWidget { }, ); }, + onLongPress: () => imageSaveDialog( + context: context, + title: coinItem.title, + cover: coinItem.pic, + ), child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ AspectRatio( aspectRatio: StyleString.aspectRatio, @@ -62,10 +68,11 @@ class MemberCoinsItem extends StatelessWidget { Padding( padding: const EdgeInsets.fromLTRB(5, 6, 0, 0), child: Column( + crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( - coinItem.title!, + '${coinItem.title}\n', maxLines: 2, overflow: TextOverflow.ellipsis, ), diff --git a/lib/pages/member_like/controller.dart b/lib/pages/member_like/controller.dart index 1d2e9c7cb..22011deed 100644 --- a/lib/pages/member_like/controller.dart +++ b/lib/pages/member_like/controller.dart @@ -1,3 +1,18 @@ -import 'package:get/get.dart'; +import 'package:PiliPlus/http/loading_state.dart'; +import 'package:PiliPlus/http/member.dart'; +import 'package:PiliPlus/pages/common/common_controller.dart'; -class MemberLikeController extends GetxController {} +class MemberLikeController extends CommonController { + final dynamic mid; + MemberLikeController({this.mid}); + + @override + void onInit() { + super.onInit(); + queryData(); + } + + @override + Future customGetData() => + MemberHttp.getRecentLikeVideo(mid: mid); +} diff --git a/lib/pages/member_like/view.dart b/lib/pages/member_like/view.dart index ca33d569d..49d177440 100644 --- a/lib/pages/member_like/view.dart +++ b/lib/pages/member_like/view.dart @@ -1,15 +1,75 @@ +import 'package:PiliPlus/common/constants.dart'; +import 'package:PiliPlus/common/widgets/loading_widget.dart'; +import 'package:PiliPlus/http/loading_state.dart'; +import 'package:PiliPlus/pages/member_coin/widgets/item.dart'; +import 'package:PiliPlus/pages/member_like/controller.dart'; +import 'package:PiliPlus/utils/grid.dart'; +import 'package:PiliPlus/utils/storage.dart'; +import 'package:PiliPlus/utils/utils.dart'; import 'package:flutter/material.dart'; +import 'package:get/get.dart'; class MemberLikePage extends StatefulWidget { - const MemberLikePage({super.key}); + const MemberLikePage({ + super.key, + required this.mid, + this.name, + }); + + final dynamic mid; + final String? name; @override State createState() => _MemberLikePageState(); } class _MemberLikePageState extends State { + late final _ownerMid = GStorage.ownerMid; + + late final _ctr = Get.put( + MemberLikeController(mid: widget.mid), + tag: Utils.makeHeroTag(widget.mid), + ); + @override Widget build(BuildContext context) { - return Scaffold(); + return Scaffold( + appBar: AppBar( + title: Text('${widget.mid == _ownerMid ? '我' : '${widget.name}'}的推荐'), + ), + body: Obx(() => _buildBody(_ctr.loadingState.value)), + ); + } + + Widget _buildBody(LoadingState loadingState) { + return switch (loadingState) { + Loading() => loadingWidget, + Success() => (loadingState.response as List?)?.isNotEmpty == true + ? GridView.builder( + padding: EdgeInsets.only( + top: StyleString.safeSpace - 5, + left: StyleString.safeSpace, + right: StyleString.safeSpace, + bottom: MediaQuery.paddingOf(context).bottom + 80, + ), + gridDelegate: SliverGridDelegateWithExtentAndRatio( + mainAxisSpacing: StyleString.cardSpace, + crossAxisSpacing: StyleString.cardSpace, + maxCrossAxisExtent: Grid.smallCardWidth, + childAspectRatio: StyleString.aspectRatio, + mainAxisExtent: MediaQuery.textScalerOf(context).scale(75), + ), + itemCount: loadingState.response.length, + itemBuilder: (context, index) { + return MemberCoinsItem(coinItem: loadingState.response[index]); + }, + ) + : scrollErrorWidget(callback: _ctr.onReload), + Error() => scrollErrorWidget( + errMsg: loadingState.errMsg, + callback: _ctr.onReload, + ), + LoadingState() => throw UnimplementedError(), + }; } } diff --git a/lib/router/app_pages.dart b/lib/router/app_pages.dart index c8ed0c676..4822f9b1f 100644 --- a/lib/router/app_pages.dart +++ b/lib/router/app_pages.dart @@ -32,9 +32,7 @@ import '../pages/live_room/view.dart'; import '../pages/login/index.dart'; import '../pages/media/index.dart'; import '../pages/member_archive/index.dart'; -import '../pages/member_coin/index.dart'; import '../pages/member_dynamics/index.dart'; -import '../pages/member_like/index.dart'; import '../pages/member_search/index.dart'; import '../pages/member_seasons/index.dart'; import '../pages/msg_feed_top/sys_msg/view.dart'; @@ -154,9 +152,9 @@ class Routes { CustomGetPage( name: '/memberArchive', page: () => const MemberArchivePage()), // 用户最近投币 - CustomGetPage(name: '/memberCoin', page: () => const MemberCoinPage()), + // CustomGetPage(name: '/memberCoin', page: () => const MemberCoinPage()), // 用户最近喜欢 - CustomGetPage(name: '/memberLike', page: () => const MemberLikePage()), + // CustomGetPage(name: '/memberLike', page: () => const MemberLikePage()), // 用户专栏 CustomGetPage( name: '/memberSeasons', page: () => const MemberSeasonsPage()), diff --git a/lib/utils/storage.dart b/lib/utils/storage.dart index 1c08754f4..593eb2427 100644 --- a/lib/utils/storage.dart +++ b/lib/utils/storage.dart @@ -34,6 +34,8 @@ class GStorage { static bool get isLogin => userInfo.get('userInfoCache') != null; + static get ownerMid => GStorage.userInfo.get('userInfoCache')?.mid; + static List get speedList => List.from( video.get( VideoBoxKey.speedsList,