mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-06-01 16:48:16 +08:00
fix: multi vote
Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
@@ -164,16 +164,29 @@ class _VotePanelState extends State<VotePanel> {
|
|||||||
|
|
||||||
Widget _buildOptions(int index) {
|
Widget _buildOptions(int index) {
|
||||||
final opt = _voteInfo.options[index];
|
final opt = _voteInfo.options[index];
|
||||||
|
final selected = groupValue.contains(opt.optidx);
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 4),
|
padding: const EdgeInsets.symmetric(vertical: 4),
|
||||||
child: PercentageChip<int>(
|
child: PercentageChip<int>(
|
||||||
label: opt.optdesc!,
|
label: opt.optdesc!,
|
||||||
value: opt.optidx!,
|
|
||||||
groupValue: groupValue,
|
|
||||||
disabled: groupValue.length >= _maxCnt,
|
|
||||||
percentage: _showPercentage ? _percentage[index] : null,
|
percentage: _showPercentage ? _percentage[index] : null,
|
||||||
callback: _enabled ? _toggleSelection : null,
|
selected: selected,
|
||||||
));
|
onSelected: !_enabled || (groupValue.length >= _maxCnt && !selected)
|
||||||
|
? null
|
||||||
|
: (value) => _onSelected(value, opt.optidx!),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onSelected(bool value, int optidx) {
|
||||||
|
if (value) {
|
||||||
|
groupValue.add(optidx);
|
||||||
|
} else {
|
||||||
|
groupValue.remove(optidx);
|
||||||
|
}
|
||||||
|
_selectedNum.value = groupValue.length;
|
||||||
|
_canVote.value = groupValue.isNotEmpty;
|
||||||
|
setState(() {});
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildContext() {
|
Widget _buildContext() {
|
||||||
@@ -204,52 +217,22 @@ class _VotePanelState extends State<VotePanel> {
|
|||||||
? List<double>.filled(options.length, 0)
|
? List<double>.filled(options.length, 0)
|
||||||
: options.map((i) => i.cnt / total).toList(growable: false);
|
: options.map((i) => i.cnt / total).toList(growable: false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _toggleSelection(bool val) {
|
|
||||||
_selectedNum.value = groupValue.length;
|
|
||||||
_canVote.value = groupValue.isNotEmpty;
|
|
||||||
if (groupValue.length >= _maxCnt ||
|
|
||||||
(!val && groupValue.length + 1 == _maxCnt)) {
|
|
||||||
setState(() {});
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class PercentageChip<T> extends StatefulWidget {
|
class PercentageChip<T> extends StatelessWidget {
|
||||||
final String label;
|
final String label;
|
||||||
final T value;
|
|
||||||
final Set<T> groupValue;
|
|
||||||
final double? percentage;
|
final double? percentage;
|
||||||
final bool disabled;
|
final bool selected;
|
||||||
final bool? Function(bool)? callback;
|
final ValueChanged<bool>? onSelected;
|
||||||
|
|
||||||
const PercentageChip({
|
const PercentageChip({
|
||||||
super.key,
|
super.key,
|
||||||
required this.label,
|
required this.label,
|
||||||
required this.value,
|
required this.selected,
|
||||||
required this.groupValue,
|
required this.onSelected,
|
||||||
this.disabled = false,
|
|
||||||
this.percentage,
|
this.percentage,
|
||||||
this.callback,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
|
||||||
State<PercentageChip<T>> createState() => _PercentageChipState<T>();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _PercentageChipState<T> extends State<PercentageChip<T>> {
|
|
||||||
late Set<T> groupValue;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
groupValue = widget.groupValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool get selected => groupValue.contains(widget.value);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final colorScheme = Theme.of(context).colorScheme;
|
final colorScheme = Theme.of(context).colorScheme;
|
||||||
@@ -262,12 +245,12 @@ class _PercentageChipState<T> extends State<PercentageChip<T>> {
|
|||||||
clipBehavior: Clip.none,
|
clipBehavior: Clip.none,
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
children: [
|
children: [
|
||||||
if (widget.percentage != null)
|
if (percentage != null)
|
||||||
Positioned.fill(
|
Positioned.fill(
|
||||||
left: 0,
|
left: 0,
|
||||||
child: FractionallySizedBox(
|
child: FractionallySizedBox(
|
||||||
alignment: Alignment.centerLeft,
|
alignment: Alignment.centerLeft,
|
||||||
widthFactor: widget.percentage,
|
widthFactor: percentage,
|
||||||
child: ColoredBox(
|
child: ColoredBox(
|
||||||
color: selected
|
color: selected
|
||||||
? colorScheme.inversePrimary
|
? colorScheme.inversePrimary
|
||||||
@@ -284,7 +267,7 @@ class _PercentageChipState<T> extends State<PercentageChip<T>> {
|
|||||||
Row(
|
Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
Text(widget.label),
|
Text(label),
|
||||||
if (selected)
|
if (selected)
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(left: 4),
|
padding: const EdgeInsets.only(left: 4),
|
||||||
@@ -296,22 +279,15 @@ class _PercentageChipState<T> extends State<PercentageChip<T>> {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
if (widget.percentage != null)
|
if (percentage != null)
|
||||||
Text('${(widget.percentage! * 100).toStringAsFixed(0)}%'),
|
Text('${(percentage! * 100).toStringAsFixed(0)}%'),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
selected: selected,
|
selected: selected,
|
||||||
onSelected: widget.disabled && (!selected || widget.callback == null)
|
onSelected: onSelected,
|
||||||
? null
|
|
||||||
: (value) {
|
|
||||||
value
|
|
||||||
? groupValue.add(widget.value)
|
|
||||||
: groupValue.remove(widget.value);
|
|
||||||
if (widget.callback?.call(value) == true) setState(() {});
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user