From 2cfad80214be82fb59259cde02377d0bfa797e26 Mon Sep 17 00:00:00 2001 From: My-Responsitories <107370289+My-Responsitories@users.noreply.github.com> Date: Sun, 4 May 2025 13:53:00 +0800 Subject: [PATCH] feat: vote pabel (#807) --- lib/common/widgets/dialog/report.dart | 56 ++- lib/http/api.dart | 4 + lib/http/dynamics.dart | 37 ++ .../dynamics/article_content_model.dart | 28 +- lib/models/dynamics/vote_model.dart | 63 +++ lib/pages/article/widgets/opus_content.dart | 78 ++-- .../dynamics/widgets/rich_node_panel.dart | 380 +++++++++-------- lib/pages/dynamics/widgets/vote.dart | 388 ++++++++++++++++++ .../video/reply/widgets/reply_item_grpc.dart | 21 +- 9 files changed, 755 insertions(+), 300 deletions(-) create mode 100644 lib/models/dynamics/vote_model.dart create mode 100644 lib/pages/dynamics/widgets/vote.dart diff --git a/lib/common/widgets/dialog/report.dart b/lib/common/widgets/dialog/report.dart index cd4f3326..a81789a0 100644 --- a/lib/common/widgets/dialog/report.dart +++ b/lib/common/widgets/dialog/report.dart @@ -61,7 +61,11 @@ void autoWrapReportDialog( ), ), ), - BanUserCheckbox(onChanged: (value) => banUid = value), + Padding( + padding: const EdgeInsets.only(left: 14, top: 6), + child: CheckBoxText( + text: '拉黑该用户', onChanged: (value) => banUid = value), + ), ], ), ), @@ -145,44 +149,58 @@ class _ReasonFieldState extends State { } } -class BanUserCheckbox extends StatefulWidget { +class CheckBoxText extends StatefulWidget { + final String text; final ValueChanged onChanged; + final bool selected; - const BanUserCheckbox({super.key, required this.onChanged}); + const CheckBoxText({ + super.key, + required this.text, + required this.onChanged, + this.selected = false, + }); @override - State createState() => _BanUserCheckboxState(); + State createState() => _CheckBoxTextState(); } -class _BanUserCheckboxState extends State { - bool _banUid = false; +class _CheckBoxTextState extends State { + late bool _selected; + + @override + void initState() { + super.initState(); + _selected = widget.selected; + } @override Widget build(BuildContext context) { - final theme = Theme.of(context); - return GestureDetector( + final colorScheme = Theme.of(context).colorScheme; + return InkWell( onTap: () { - setState(() => _banUid = !_banUid); - widget.onChanged(_banUid); + setState(() { + _selected = !_selected; + }); + widget.onChanged(_selected); }, child: Padding( - padding: const EdgeInsets.only(left: 18, top: 10), + padding: const EdgeInsets.all(4), child: Row( + mainAxisSize: MainAxisSize.min, children: [ Icon( size: 22, - _banUid + _selected ? Icons.check_box_outlined : Icons.check_box_outline_blank, - color: _banUid - ? theme.colorScheme.primary - : theme.colorScheme.onSurfaceVariant, + color: _selected + ? colorScheme.primary + : colorScheme.onSurfaceVariant, ), Text( - ' 拉黑该用户', - style: TextStyle( - color: _banUid ? theme.colorScheme.primary : null, - ), + ' ${widget.text}', + style: TextStyle(color: _selected ? colorScheme.primary : null), ), ], ), diff --git a/lib/http/api.dart b/lib/http/api.dart index ba852dbc..947c02e2 100644 --- a/lib/http/api.dart +++ b/lib/http/api.dart @@ -795,4 +795,8 @@ class Api { static const String gaiaVgateRegister = '/x/gaia-vgate/v1/register'; static const String gaiaVgateValidate = '/x/gaia-vgate/v1/validate'; + + static const String voteInfo = '/x/vote/vote_info'; + + static const String doVote = '/x/vote/do_vote'; } diff --git a/lib/http/dynamics.dart b/lib/http/dynamics.dart index 1c84add7..eee64ae9 100644 --- a/lib/http/dynamics.dart +++ b/lib/http/dynamics.dart @@ -4,6 +4,7 @@ import 'package:PiliPlus/http/init.dart'; import 'package:PiliPlus/http/loading_state.dart'; import 'package:PiliPlus/models/dynamics/result.dart'; import 'package:PiliPlus/models/dynamics/up.dart'; +import 'package:PiliPlus/models/dynamics/vote_model.dart'; import 'package:PiliPlus/models/space_article/item.dart'; import 'package:PiliPlus/utils/accounts/account.dart'; import 'package:PiliPlus/utils/storage.dart'; @@ -219,4 +220,40 @@ class DynamicsHttp { ? LoadingState.success(DynamicItemModel.fromOpusJson(res.data['data'])) : LoadingState.error(res.data['message']); } + + static Future> voteInfo(dynamic voteId) async { + final res = + await Request().get(Api.voteInfo, queryParameters: {'vote_id': voteId}); + + return res.data['code'] == 0 + ? LoadingState.success(VoteInfo.fromSeparatedJson(res.data['data'])) + : LoadingState.error(res.data['message']); + } + + static Future> doVote({ + required int voteId, + required List votes, + bool anonymity = false, + int? dynamicId, + }) async { + final csrf = Accounts.main.csrf; + final data = { + 'vote_id': 15141778, + 'votes': votes, + 'voter_uid': Accounts.main.mid, + 'status': anonymity ? 1 : 0, + 'op_bit': 0, + 'dynamic_id': dynamicId ?? 0, + 'csrf_token': csrf, + 'csrf': csrf + }; + final res = await Request().post(Api.doVote, + queryParameters: {'csrf': csrf}, + data: data, + options: Options(contentType: Headers.jsonContentType)); + + return res.data['code'] == 0 + ? LoadingState.success(VoteInfo.fromJson(res.data['data']['vote_info'])) + : LoadingState.error(res.data['message']); + } } diff --git a/lib/models/dynamics/article_content_model.dart b/lib/models/dynamics/article_content_model.dart index feb7c7b8..e60664d9 100644 --- a/lib/models/dynamics/article_content_model.dart +++ b/lib/models/dynamics/article_content_model.dart @@ -1,3 +1,5 @@ +import 'package:PiliPlus/models/dynamics/vote_model.dart'; + class ArticleContentModel { int? align; int? paraType; @@ -188,7 +190,7 @@ class Card { Common? common; Live? live; Opus? opus; - Vote? vote; + SimpleVoteInfo? vote; Music? music; Goods? goods; @@ -201,7 +203,7 @@ class Card { common = json['common'] == null ? null : Common.fromJson(json['common']); live = json['live'] == null ? null : Live.fromJson(json['live']); opus = json['opus'] == null ? null : Opus.fromJson(json['opus']); - vote = json['vote'] == null ? null : Vote.fromJson(json['vote']); + vote = json['vote'] == null ? null : SimpleVoteInfo.fromJson(json['vote']); music = json['music'] == null ? null : Music.fromJson(json['music']); goods = json['goods'] == null ? null : Goods.fromJson(json['goods']); } @@ -259,28 +261,6 @@ class Music { } } -class Vote { - int? choiceCnt; - int? defaultShare; - String? desc; - int? endTime; - int? status; - int? uid; - int? voteId; - late int joinNum; - - Vote.fromJson(Map json) { - choiceCnt = json['choice_cnt']; - defaultShare = json['default_share']; - desc = json['desc']; - endTime = json['end_time']; - status = json['status']; - uid = json['uid']; - voteId = json['vote_id']; - joinNum = json['join_num'] ?? 0; - } -} - class Opus { int? authorMid; String? authorName; diff --git a/lib/models/dynamics/vote_model.dart b/lib/models/dynamics/vote_model.dart new file mode 100644 index 00000000..7a945e06 --- /dev/null +++ b/lib/models/dynamics/vote_model.dart @@ -0,0 +1,63 @@ +class SimpleVoteInfo { + int? choiceCnt; + int? defaultShare; + String? desc; + int? endTime; + int? status; + int? uid; + int? voteId; + late int joinNum; + + SimpleVoteInfo.fromJson(Map json) { + choiceCnt = json['choice_cnt']; + defaultShare = json['default_share']; + desc = json['desc']; + endTime = json['end_time']; + status = json['status']; + uid = json['uid']; + voteId = json['vote_id']; + joinNum = json['join_num'] ?? 0; + } +} + +class VoteInfo extends SimpleVoteInfo { + String? title; + int? ctime; + List? myVotes; + late List