mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-05-26 11:08:44 +00:00
opt vote panel
Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
@@ -44,14 +44,75 @@ class _VotePanelState extends State<VotePanel> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final theme = Theme.of(context);
|
final theme = Theme.of(context);
|
||||||
return Column(
|
final usePortrait =
|
||||||
|
context.orientation == Orientation.portrait || context.isTablet;
|
||||||
|
final right = [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
_enabled
|
||||||
|
? '投票选项'
|
||||||
|
: groupValue.isEmpty
|
||||||
|
? '已结束'
|
||||||
|
: '已完成',
|
||||||
|
),
|
||||||
|
if (_enabled) Obx(() => Text('${groupValue.length} / $_maxCnt')),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Flexible(
|
||||||
|
child: ListView.builder(
|
||||||
|
key: const PageStorageKey('vote_opions'),
|
||||||
|
shrinkWrap: true,
|
||||||
|
itemCount: _voteInfo.options.length,
|
||||||
|
itemBuilder: (context, index) => _buildOptions(index),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (_enabled) ...[
|
||||||
|
_checkBoxs,
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 8),
|
||||||
|
child: Obx(
|
||||||
|
() => OutlinedButton(
|
||||||
|
onPressed: groupValue.isNotEmpty
|
||||||
|
? () async {
|
||||||
|
final res = await widget.callback(
|
||||||
|
groupValue,
|
||||||
|
anonymity,
|
||||||
|
);
|
||||||
|
if (res.isSuccess) {
|
||||||
|
if (mounted) {
|
||||||
|
setState(() {
|
||||||
|
_enabled = false;
|
||||||
|
_showPercentage = true;
|
||||||
|
_voteInfo = res.data;
|
||||||
|
_percentage = _cnt2Percentage(_voteInfo.options);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
res.toast();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
child: const Center(child: Text('投票')),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
];
|
||||||
|
Widget child = Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
if (_voteInfo.title != null)
|
if (_voteInfo.title != null)
|
||||||
Text(_voteInfo.title!, style: theme.textTheme.titleMedium),
|
Text(_voteInfo.title!, style: theme.textTheme.titleMedium),
|
||||||
if (_voteInfo.desc != null)
|
if (_voteInfo.desc != null)
|
||||||
Text(_voteInfo.desc!, style: theme.textTheme.titleSmall),
|
Text(
|
||||||
|
_voteInfo.desc!,
|
||||||
|
style: theme.textTheme.titleSmall!.copyWith(
|
||||||
|
color: theme.colorScheme.onSurfaceVariant.withValues(alpha: 0.8),
|
||||||
|
),
|
||||||
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 8),
|
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||||
child: Wrap(
|
child: Wrap(
|
||||||
@@ -75,71 +136,49 @@ class _VotePanelState extends State<VotePanel> {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Row(
|
if (usePortrait) ...right,
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
_enabled
|
|
||||||
? '投票选项'
|
|
||||||
: groupValue.isEmpty
|
|
||||||
? '已结束'
|
|
||||||
: '已完成',
|
|
||||||
),
|
|
||||||
if (_enabled) Obx(() => Text('${groupValue.length} / $_maxCnt')),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Flexible(fit: FlexFit.loose, child: _buildContext()),
|
|
||||||
if (_enabled)
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.only(top: 16),
|
|
||||||
child: Obx(
|
|
||||||
() => OutlinedButton(
|
|
||||||
onPressed: groupValue.isNotEmpty
|
|
||||||
? () async {
|
|
||||||
final res = await widget.callback(
|
|
||||||
groupValue,
|
|
||||||
anonymity,
|
|
||||||
);
|
|
||||||
if (res.isSuccess) {
|
|
||||||
if (mounted) {
|
|
||||||
setState(() {
|
|
||||||
_enabled = false;
|
|
||||||
_showPercentage = true;
|
|
||||||
_voteInfo = res.data;
|
|
||||||
_percentage = _cnt2Percentage(_voteInfo.options);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
res.toast();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
: null,
|
|
||||||
child: const Center(child: Text('投票')),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
if (!usePortrait) {
|
||||||
|
child = Row(
|
||||||
|
spacing: 12,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Expanded(child: child),
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: right,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return child;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Widget> get _checkBoxs => [
|
Widget get _checkBoxs => Row(
|
||||||
CheckBoxText(
|
spacing: 16,
|
||||||
text: '显示比例',
|
children: [
|
||||||
selected: _showPercentage,
|
CheckBoxText(
|
||||||
onChanged: (value) {
|
text: '显示比例',
|
||||||
setState(() {
|
selected: _showPercentage,
|
||||||
_showPercentage = value;
|
onChanged: (value) {
|
||||||
});
|
setState(() {
|
||||||
},
|
_showPercentage = value;
|
||||||
),
|
});
|
||||||
CheckBoxText(
|
},
|
||||||
text: '匿名',
|
),
|
||||||
selected: anonymity,
|
CheckBoxText(
|
||||||
onChanged: (val) {
|
text: '匿名',
|
||||||
anonymity = val;
|
selected: anonymity,
|
||||||
},
|
onChanged: (val) {
|
||||||
),
|
anonymity = val;
|
||||||
];
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
Widget _buildOptions(int index) {
|
Widget _buildOptions(int index) {
|
||||||
return Padding(
|
return Padding(
|
||||||
@@ -178,19 +217,6 @@ class _VotePanelState extends State<VotePanel> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildContext() {
|
|
||||||
return CustomScrollView(
|
|
||||||
shrinkWrap: true,
|
|
||||||
slivers: [
|
|
||||||
SliverList.builder(
|
|
||||||
itemCount: _voteInfo.options.length,
|
|
||||||
itemBuilder: (context, index) => _buildOptions(index),
|
|
||||||
),
|
|
||||||
if (_enabled) SliverList.list(children: _checkBoxs),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
static List<double> _cnt2Percentage(List<Option> options) {
|
static List<double> _cnt2Percentage(List<Option> options) {
|
||||||
final total = options.fold(0, (sum, opt) => sum + opt.cnt);
|
final total = options.fold(0, (sum, opt) => sum + opt.cnt);
|
||||||
return total == 0
|
return total == 0
|
||||||
@@ -288,16 +314,19 @@ Future showVoteDialog(
|
|||||||
if (voteInfo.isSuccess) {
|
if (voteInfo.isSuccess) {
|
||||||
showDialog(
|
showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => AlertDialog(
|
builder: (context) => Dialog(
|
||||||
content: SizedBox(
|
child: ConstrainedBox(
|
||||||
width: 160,
|
constraints: const BoxConstraints(maxWidth: 625),
|
||||||
child: VotePanel(
|
child: Padding(
|
||||||
voteInfo: voteInfo.data,
|
padding: const EdgeInsets.all(24),
|
||||||
callback: (votes, anonymity) => DynamicsHttp.doVote(
|
child: VotePanel(
|
||||||
voteId: voteId,
|
voteInfo: voteInfo.data,
|
||||||
votes: votes.toList(),
|
callback: (votes, anonymity) => DynamicsHttp.doVote(
|
||||||
anonymity: anonymity,
|
voteId: voteId,
|
||||||
dynamicId: dynamicId,
|
votes: votes.toList(),
|
||||||
|
anonymity: anonymity,
|
||||||
|
dynamicId: dynamicId,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
Reference in New Issue
Block a user