diff --git a/lib/api/marianumcloud/talk/getPoll/getPollStateResponse.g.dart b/lib/api/marianumcloud/talk/getPoll/getPollStateResponse.g.dart index f54d062..9d89f4c 100644 --- a/lib/api/marianumcloud/talk/getPoll/getPollStateResponse.g.dart +++ b/lib/api/marianumcloud/talk/getPoll/getPollStateResponse.g.dart @@ -7,54 +7,56 @@ part of 'getPollStateResponse.dart'; // ************************************************************************** GetPollStateResponse _$GetPollStateResponseFromJson( - Map json) => + Map json, +) => GetPollStateResponse( - GetPollStateResponseObject.fromJson(json['data'] as Map), - )..headers = (json['headers'] as Map?)?.map( + GetPollStateResponseObject.fromJson( + json['data'] as Map, + ), + ) + ..headers = (json['headers'] as Map?)?.map( (k, e) => MapEntry(k, e as String), ); Map _$GetPollStateResponseToJson( - GetPollStateResponse instance) => - { - if (instance.headers case final value?) 'headers': value, - 'data': instance.data.toJson(), - }; + GetPollStateResponse instance, +) => { + 'headers': ?instance.headers, + 'data': instance.data.toJson(), +}; GetPollStateResponseObject _$GetPollStateResponseObjectFromJson( - Map json) => - GetPollStateResponseObject( - (json['id'] as num).toInt(), - json['question'] as String, - (json['options'] as List).map((e) => e as String).toList(), - json['votes'], - json['actorType'] as String, - json['actorId'] as String, - json['actorDisplayName'] as String, - (json['status'] as num).toInt(), - (json['resultMode'] as num).toInt(), - (json['maxVotes'] as num).toInt(), - (json['votedSelf'] as List) - .map((e) => (e as num).toInt()) - .toList(), - (json['numVoters'] as num?)?.toInt(), - (json['details'] as List?)?.map((e) => e as String).toList(), - ); + Map json, +) => GetPollStateResponseObject( + (json['id'] as num).toInt(), + json['question'] as String, + (json['options'] as List).map((e) => e as String).toList(), + json['votes'], + json['actorType'] as String, + json['actorId'] as String, + json['actorDisplayName'] as String, + (json['status'] as num).toInt(), + (json['resultMode'] as num).toInt(), + (json['maxVotes'] as num).toInt(), + (json['votedSelf'] as List).map((e) => (e as num).toInt()).toList(), + (json['numVoters'] as num?)?.toInt(), + (json['details'] as List?)?.map((e) => e as String).toList(), +); Map _$GetPollStateResponseObjectToJson( - GetPollStateResponseObject instance) => - { - 'id': instance.id, - 'question': instance.question, - 'options': instance.options, - 'votes': instance.votes, - 'actorType': instance.actorType, - 'actorId': instance.actorId, - 'actorDisplayName': instance.actorDisplayName, - 'status': instance.status, - 'resultMode': instance.resultMode, - 'maxVotes': instance.maxVotes, - 'votedSelf': instance.votedSelf, - 'numVoters': instance.numVoters, - 'details': instance.details, - }; + GetPollStateResponseObject instance, +) => { + 'id': instance.id, + 'question': instance.question, + 'options': instance.options, + 'votes': instance.votes, + 'actorType': instance.actorType, + 'actorId': instance.actorId, + 'actorDisplayName': instance.actorDisplayName, + 'status': instance.status, + 'resultMode': instance.resultMode, + 'maxVotes': instance.maxVotes, + 'votedSelf': instance.votedSelf, + 'numVoters': instance.numVoters, + 'details': instance.details, +}; diff --git a/lib/api/marianumcloud/talk/votePoll/votePoll.dart b/lib/api/marianumcloud/talk/votePoll/votePoll.dart index 076b49f..a0880bd 100644 --- a/lib/api/marianumcloud/talk/votePoll/votePoll.dart +++ b/lib/api/marianumcloud/talk/votePoll/votePoll.dart @@ -8,6 +8,7 @@ import '../getPoll/getPollStateResponse.dart'; import '../talkApi.dart'; import 'votePollParams.dart'; +@Deprecated('VotePoll is broken (known issues)') class VotePoll extends TalkApi { String token; int pollId; diff --git a/lib/api/marianumcloud/talk/votePoll/votePollParams.g.dart b/lib/api/marianumcloud/talk/votePoll/votePollParams.g.dart index cb7d6f0..5b43858 100644 --- a/lib/api/marianumcloud/talk/votePoll/votePollParams.g.dart +++ b/lib/api/marianumcloud/talk/votePoll/votePollParams.g.dart @@ -14,6 +14,4 @@ VotePollParams _$VotePollParamsFromJson(Map json) => ); Map _$VotePollParamsToJson(VotePollParams instance) => - { - 'optionIds': instance.optionIds, - }; + {'optionIds': instance.optionIds}; diff --git a/lib/view/pages/talk/components/chatBubble.dart b/lib/view/pages/talk/components/chatBubble.dart index 2fd7ef9..5ce3b97 100644 --- a/lib/view/pages/talk/components/chatBubble.dart +++ b/lib/view/pages/talk/components/chatBubble.dart @@ -7,8 +7,6 @@ import 'package:flutter/services.dart'; import 'package:jiffy/jiffy.dart'; import 'package:open_filex/open_filex.dart'; import '../../../../api/marianumcloud/talk/getPoll/getPollState.dart'; -import '../../../../api/marianumcloud/talk/votePoll/votePoll.dart'; -import '../../../../api/marianumcloud/talk/votePoll/votePollParams.dart'; import '../../../../extensions/text.dart'; import 'package:provider/provider.dart'; @@ -305,7 +303,6 @@ class _ChatBubbleState extends State with SingleTickerProviderStateM if(message.originalData?['object']?.type == RichObjectStringObjectType.talkPoll) { var pollId = int.parse(message.originalData!['object']!.id); var pollState = GetPollState(token: widget.bubbleData.token, pollId: pollId).run(); - List? ownVotes; showDialog(context: context, builder: (context) => AlertDialog( title: Text(message.originalData!['object']!.name, textScaler: TextScaler.linear(0.9)), content: FutureBuilder( @@ -314,26 +311,20 @@ class _ChatBubbleState extends State with SingleTickerProviderStateM if(snapshot.connectionState == ConnectionState.waiting) return const Column(mainAxisSize: MainAxisSize.min, children: [LoadingSpinner()]); var pollData = snapshot.data!.data; - ownVotes = pollData.votedSelf; - return PollOptionsList( - pollData: pollData, - callback: (votes) => ownVotes = votes + return ListView( + shrinkWrap: true, + children: [ + PollOptionsList( + pollData: pollData + ) + ] ); } ), actions: [ - FutureBuilder(future: pollState, builder: (context, snapshot) => TextButton( - onPressed: () async { - if(snapshot.connectionState != ConnectionState.done) return; - Navigator.of(context).pop(); - if(ownVotes == null) return; - VotePoll(pollId: pollId, token: widget.bubbleData.token, params: VotePollParams(optionIds: ownVotes!)).run(); - }, - child: const Text('Stimme abgeben') - )), TextButton( onPressed: () => Navigator.of(context).pop(), - child: const Text('Abbrechen') + child: const Text('Zurück') ), ], )); diff --git a/lib/view/pages/talk/components/pollOptionsList.dart b/lib/view/pages/talk/components/pollOptionsList.dart index db26406..b3d2426 100644 --- a/lib/view/pages/talk/components/pollOptionsList.dart +++ b/lib/view/pages/talk/components/pollOptionsList.dart @@ -1,45 +1,69 @@ + import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_linkify/flutter_linkify.dart'; import '../../../../api/marianumcloud/talk/getPoll/getPollStateResponse.dart'; class PollOptionsList extends StatefulWidget { final GetPollStateResponseObject pollData; - final Function(List) callback; - const PollOptionsList({super.key, required this.pollData, required this.callback}); + const PollOptionsList({super.key, required this.pollData}); @override State createState() => _PollOptionsListState(); } class _PollOptionsListState extends State { - late List ownVotes; - - @override - void initState() { - super.initState(); - ownVotes = widget.pollData.votedSelf; - } - @override Widget build(BuildContext context) => Column( mainAxisSize: MainAxisSize.min, children: [ - ...widget.pollData.options.map((option) => CheckboxListTile( - value: ownVotes.contains(widget.pollData.options.indexOf(option)), - title: Text(option), - onChanged: (value) { - var optionId = widget.pollData.options.indexOf(option); - setState(() { - if(ownVotes.contains(optionId)) { - ownVotes.remove(optionId); - } else { - ownVotes.add(optionId); - } - }); - widget.callback(ownVotes); - } - ) + ...widget.pollData.options.map((option) { + var optionId = widget.pollData.options.indexOf(option); + var votedSelf = widget.pollData.votedSelf.contains(optionId); + var votes = widget.pollData.votes.runtimeType is Map + ? widget.pollData.votes['option-$optionId'] + : 0; + int numVoters = 1; + if(widget.pollData.numVoters != null && widget.pollData.numVoters != 0) { + numVoters = widget.pollData.numVoters!; + } + var portion = (votes / numVoters); + return ListTile( + enabled: false, + isThreeLine: true, + title: Text( + option, + style: Theme.of(context).textTheme.bodyLarge, + ), + trailing: Icon( + votedSelf ? Icons.check_circle_outlined : Icons.circle_outlined, + color: votedSelf + ? Theme.of(context).colorScheme.primary.withValues(alpha: 0.8) + : Theme.of(context).colorScheme.onSurfaceVariant.withValues(alpha: 0.8), + ), + subtitle: Visibility( + visible: widget.pollData.numVoters != null, + child: Row( + children: [ + Expanded( + child: LinearProgressIndicator(value: portion), + ), + Container( + margin: const EdgeInsets.only(left: 10), + child: Text('${(portion * 100).round()}%'), + ), + ], + ) + ) + ); + }), + ListTile( + title: Linkify( + text: 'Zurzeit kann in dieser App leider nicht an Abstimmungen teilgenommen werden. ' + 'Um abzustimmen verwende die Webversion unter https://cloud.marianum-fulda.de', + style: Theme.of(context).textTheme.bodySmall, + ), ) ], );