|
| 1 | +import 'dart:async'; |
| 2 | + |
1 | 3 | import 'package:flutter/material.dart';
|
2 | 4 | import 'package:flutter_gen/gen_l10n/zulip_localizations.dart';
|
3 | 5 |
|
4 | 6 | import '../api/model/submessage.dart';
|
| 7 | +import '../api/route/submessage.dart'; |
5 | 8 | import 'content.dart';
|
6 | 9 | import 'store.dart';
|
7 | 10 | import 'text.dart';
|
8 | 11 |
|
9 | 12 | class PollWidget extends StatefulWidget {
|
10 |
| - const PollWidget({super.key, required this.poll}); |
| 13 | + const PollWidget({super.key, required this.messageId, required this.poll}); |
11 | 14 |
|
| 15 | + final int messageId; |
12 | 16 | final Poll poll;
|
13 | 17 |
|
14 | 18 | @override
|
@@ -44,6 +48,18 @@ class _PollWidgetState extends State<PollWidget> {
|
44 | 48 | });
|
45 | 49 | }
|
46 | 50 |
|
| 51 | + void _toggleVote(PollOption option) async { |
| 52 | + final store = PerAccountStoreWidget.of(context); |
| 53 | + // The poll data in store might be obselete before we get the event |
| 54 | + // that updates it. This is fine because the result will be consistent |
| 55 | + // eventually, regardless of the possible duplicate requests. |
| 56 | + final op = widget.poll.hasUserVotedFor(userId: store.selfUserId, key: option.key) |
| 57 | + ? PollVoteOp.remove |
| 58 | + : PollVoteOp.add; |
| 59 | + unawaited(sendSubmessage(store.connection, messageId: widget.messageId, |
| 60 | + content: PollVoteEventSubmessage(key: option.key, op: op))); |
| 61 | + } |
| 62 | + |
47 | 63 | @override
|
48 | 64 | Widget build(BuildContext context) {
|
49 | 65 | final zulipLocalizations = ZulipLocalizations.of(context);
|
@@ -73,25 +89,32 @@ class _PollWidgetState extends State<PollWidget> {
|
73 | 89 | crossAxisAlignment: CrossAxisAlignment.baseline,
|
74 | 90 | textBaseline: localizedTextBaseline(context),
|
75 | 91 | children: [
|
76 |
| - ConstrainedBox( |
77 |
| - constraints: const BoxConstraints( |
78 |
| - minWidth: 39 + 5).tighten(height: 39 + verticalPadding * 2), |
79 |
| - child: Padding( |
80 |
| - padding: const EdgeInsetsDirectional.only( |
81 |
| - end: 5, top: verticalPadding, bottom: verticalPadding), |
82 |
| - child: Container( |
83 |
| - // This is only in effect |
84 |
| - // when the vote count has more than 2 digits. |
85 |
| - padding: const EdgeInsets.symmetric(horizontal: 4), |
86 |
| - decoration: BoxDecoration( |
87 |
| - color: theme.colorPollVoteCountBackground, |
88 |
| - border: Border.all(color: theme.colorPollVoteCountBorder), |
89 |
| - borderRadius: BorderRadius.circular(3)), |
90 |
| - child: Center( |
91 |
| - child: Text(option.voters.length.toString(), |
92 |
| - textAlign: TextAlign.center, |
93 |
| - style: textStyleBold.copyWith( |
94 |
| - color: theme.colorPollVoteCountText, fontSize: 18)))))), |
| 92 | + GestureDetector( |
| 93 | + onTap: () => _toggleVote(option), |
| 94 | + behavior: HitTestBehavior.translucent, |
| 95 | + child: ConstrainedBox( |
| 96 | + constraints: const BoxConstraints( |
| 97 | + minWidth: 39 + 5).tighten(height: 39 + verticalPadding * 2), |
| 98 | + child: Padding( |
| 99 | + // For accessibility, the touch target is padded to be larger |
| 100 | + // than the vote count box. Still, we avoid padding at the |
| 101 | + // start because we want to align all the poll options to the |
| 102 | + // surrounding messages. |
| 103 | + padding: const EdgeInsetsDirectional.only( |
| 104 | + end: 5, top: verticalPadding, bottom: verticalPadding), |
| 105 | + child: Container( |
| 106 | + // This is only in effect |
| 107 | + // when the vote count has more than 2 digits. |
| 108 | + padding: const EdgeInsets.symmetric(horizontal: 4), |
| 109 | + decoration: BoxDecoration( |
| 110 | + color: theme.colorPollVoteCountBackground, |
| 111 | + border: Border.all(color: theme.colorPollVoteCountBorder), |
| 112 | + borderRadius: BorderRadius.circular(3)), |
| 113 | + child: Center( |
| 114 | + child: Text(option.voters.length.toString(), |
| 115 | + textAlign: TextAlign.center, |
| 116 | + style: textStyleBold.copyWith( |
| 117 | + color: theme.colorPollVoteCountText, fontSize: 18))))))), |
95 | 118 | Expanded(
|
96 | 119 | child: Wrap(
|
97 | 120 | spacing: 5,
|
|
0 commit comments