import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:material_symbols_icons/symbols.dart'; import 'package:provider/provider.dart'; import 'package:styled_widget/styled_widget.dart'; import 'package:surface/providers/sn_network.dart'; import 'package:surface/providers/userinfo.dart'; import 'package:surface/types/poll.dart'; import 'package:surface/widgets/dialog.dart'; class PostPoll extends StatefulWidget { final SnPoll poll; const PostPoll({super.key, required this.poll}); @override State createState() => _PostPollState(); } class _PostPollState extends State { bool _isBusy = false; late SnPoll _poll; @override void initState() { _poll = widget.poll; _fetchAnswer(); super.initState(); } String? _answeredChoice; Future _fetchAnswer() async { final ua = context.read(); if (!ua.isAuthorized) return; try { setState(() => _isBusy = true); final sn = context.read(); final resp = await sn.client.get('/cgi/co/polls/${widget.poll.id}/answer'); _answeredChoice = resp.data?['answer']; if (!mounted) return; setState(() {}); } catch (err) { if (!mounted) return; context.showErrorDialog(err); } finally { setState(() => _isBusy = false); } } Future _voteForOption(SnPollOption option) async { final ua = context.read(); if (!ua.isAuthorized) return; try { setState(() => _isBusy = true); final sn = context.read(); await sn.client.post('/cgi/co/polls/${widget.poll.id}/answer', data: { 'answer': option.id, }); if (!mounted) return; context.showSnackbar('pollAnswered'.tr()); HapticFeedback.heavyImpact(); } catch (err) { if (!mounted) return; context.showErrorDialog(err); } finally { setState(() => _isBusy = false); } } @override Widget build(BuildContext context) { return Card( margin: EdgeInsets.zero, child: Column( children: [ for (final option in _poll.options) Stack( children: [ Container( height: 60, width: MediaQuery.of(context).size.width * (_poll.metric.byOptionsPercentage[option.id] ?? 0).toDouble(), color: Theme.of(context).colorScheme.surfaceContainerHigh, ), ListTile( shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), minTileHeight: 60, leading: _answeredChoice == option.id ? const Icon(Symbols.circle, fill: 1) : const Icon(Symbols.circle), title: Text(option.name), subtitle: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ Row( mainAxisSize: MainAxisSize.min, children: [ Text('pollVotes'.plural(_poll.metric.byOptions[option.id] ?? 0)), Text(' ยท ').padding(horizontal: 4), Text( '${((_poll.metric.byOptionsPercentage[option.id] ?? 0).toDouble() * 100).toStringAsFixed(2)}%', ), ], ), if (option.description.isNotEmpty) Text(option.description), ], ), onTap: _isBusy ? null : () => _voteForOption(option), ), ], ) ], ), ); } }