👽 Make poll load itself to match server updates
This commit is contained in:
		@@ -8,7 +8,7 @@ part 'poll.g.dart';
 | 
			
		||||
@freezed
 | 
			
		||||
sealed class SnPollWithStats with _$SnPollWithStats {
 | 
			
		||||
  const factory SnPollWithStats({
 | 
			
		||||
    required Map<String, dynamic>? userAnswer,
 | 
			
		||||
    required SnPollAnswer? userAnswer,
 | 
			
		||||
    @Default({}) Map<String, dynamic> stats,
 | 
			
		||||
    required String id,
 | 
			
		||||
    required List<SnPollQuestion> questions,
 | 
			
		||||
 
 | 
			
		||||
@@ -15,7 +15,7 @@ T _$identity<T>(T value) => value;
 | 
			
		||||
/// @nodoc
 | 
			
		||||
mixin _$SnPollWithStats {
 | 
			
		||||
 | 
			
		||||
 Map<String, dynamic>? get userAnswer; Map<String, dynamic> get stats; String get id; List<SnPollQuestion> get questions; String? get title; String? get description; DateTime? get endedAt; String get publisherId; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt;
 | 
			
		||||
 SnPollAnswer? get userAnswer; Map<String, dynamic> get stats; String get id; List<SnPollQuestion> get questions; String? get title; String? get description; DateTime? get endedAt; String get publisherId; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt;
 | 
			
		||||
/// Create a copy of SnPollWithStats
 | 
			
		||||
/// with the given fields replaced by the non-null parameter values.
 | 
			
		||||
@JsonKey(includeFromJson: false, includeToJson: false)
 | 
			
		||||
@@ -28,12 +28,12 @@ $SnPollWithStatsCopyWith<SnPollWithStats> get copyWith => _$SnPollWithStatsCopyW
 | 
			
		||||
 | 
			
		||||
@override
 | 
			
		||||
bool operator ==(Object other) {
 | 
			
		||||
  return identical(this, other) || (other.runtimeType == runtimeType&&other is SnPollWithStats&&const DeepCollectionEquality().equals(other.userAnswer, userAnswer)&&const DeepCollectionEquality().equals(other.stats, stats)&&(identical(other.id, id) || other.id == id)&&const DeepCollectionEquality().equals(other.questions, questions)&&(identical(other.title, title) || other.title == title)&&(identical(other.description, description) || other.description == description)&&(identical(other.endedAt, endedAt) || other.endedAt == endedAt)&&(identical(other.publisherId, publisherId) || other.publisherId == publisherId)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
 | 
			
		||||
  return identical(this, other) || (other.runtimeType == runtimeType&&other is SnPollWithStats&&(identical(other.userAnswer, userAnswer) || other.userAnswer == userAnswer)&&const DeepCollectionEquality().equals(other.stats, stats)&&(identical(other.id, id) || other.id == id)&&const DeepCollectionEquality().equals(other.questions, questions)&&(identical(other.title, title) || other.title == title)&&(identical(other.description, description) || other.description == description)&&(identical(other.endedAt, endedAt) || other.endedAt == endedAt)&&(identical(other.publisherId, publisherId) || other.publisherId == publisherId)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@JsonKey(includeFromJson: false, includeToJson: false)
 | 
			
		||||
@override
 | 
			
		||||
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(userAnswer),const DeepCollectionEquality().hash(stats),id,const DeepCollectionEquality().hash(questions),title,description,endedAt,publisherId,createdAt,updatedAt,deletedAt);
 | 
			
		||||
int get hashCode => Object.hash(runtimeType,userAnswer,const DeepCollectionEquality().hash(stats),id,const DeepCollectionEquality().hash(questions),title,description,endedAt,publisherId,createdAt,updatedAt,deletedAt);
 | 
			
		||||
 | 
			
		||||
@override
 | 
			
		||||
String toString() {
 | 
			
		||||
@@ -48,11 +48,11 @@ abstract mixin class $SnPollWithStatsCopyWith<$Res>  {
 | 
			
		||||
  factory $SnPollWithStatsCopyWith(SnPollWithStats value, $Res Function(SnPollWithStats) _then) = _$SnPollWithStatsCopyWithImpl;
 | 
			
		||||
@useResult
 | 
			
		||||
$Res call({
 | 
			
		||||
 Map<String, dynamic>? userAnswer, Map<String, dynamic> stats, String id, List<SnPollQuestion> questions, String? title, String? description, DateTime? endedAt, String publisherId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
 | 
			
		||||
 SnPollAnswer? userAnswer, Map<String, dynamic> stats, String id, List<SnPollQuestion> questions, String? title, String? description, DateTime? endedAt, String publisherId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
$SnPollAnswerCopyWith<$Res>? get userAnswer;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
/// @nodoc
 | 
			
		||||
@@ -68,7 +68,7 @@ class _$SnPollWithStatsCopyWithImpl<$Res>
 | 
			
		||||
@pragma('vm:prefer-inline') @override $Res call({Object? userAnswer = freezed,Object? stats = null,Object? id = null,Object? questions = null,Object? title = freezed,Object? description = freezed,Object? endedAt = freezed,Object? publisherId = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
 | 
			
		||||
  return _then(_self.copyWith(
 | 
			
		||||
userAnswer: freezed == userAnswer ? _self.userAnswer : userAnswer // ignore: cast_nullable_to_non_nullable
 | 
			
		||||
as Map<String, dynamic>?,stats: null == stats ? _self.stats : stats // ignore: cast_nullable_to_non_nullable
 | 
			
		||||
as SnPollAnswer?,stats: null == stats ? _self.stats : stats // ignore: cast_nullable_to_non_nullable
 | 
			
		||||
as Map<String, dynamic>,id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
 | 
			
		||||
as String,questions: null == questions ? _self.questions : questions // ignore: cast_nullable_to_non_nullable
 | 
			
		||||
as List<SnPollQuestion>,title: freezed == title ? _self.title : title // ignore: cast_nullable_to_non_nullable
 | 
			
		||||
@@ -81,7 +81,19 @@ as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ign
 | 
			
		||||
as DateTime?,
 | 
			
		||||
  ));
 | 
			
		||||
}
 | 
			
		||||
/// Create a copy of SnPollWithStats
 | 
			
		||||
/// with the given fields replaced by the non-null parameter values.
 | 
			
		||||
@override
 | 
			
		||||
@pragma('vm:prefer-inline')
 | 
			
		||||
$SnPollAnswerCopyWith<$Res>? get userAnswer {
 | 
			
		||||
    if (_self.userAnswer == null) {
 | 
			
		||||
    return null;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return $SnPollAnswerCopyWith<$Res>(_self.userAnswer!, (value) {
 | 
			
		||||
    return _then(_self.copyWith(userAnswer: value));
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -160,7 +172,7 @@ return $default(_that);case _:
 | 
			
		||||
/// }
 | 
			
		||||
/// ```
 | 
			
		||||
 | 
			
		||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( Map<String, dynamic>? userAnswer,  Map<String, dynamic> stats,  String id,  List<SnPollQuestion> questions,  String? title,  String? description,  DateTime? endedAt,  String publisherId,  DateTime createdAt,  DateTime updatedAt,  DateTime? deletedAt)?  $default,{required TResult orElse(),}) {final _that = this;
 | 
			
		||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( SnPollAnswer? userAnswer,  Map<String, dynamic> stats,  String id,  List<SnPollQuestion> questions,  String? title,  String? description,  DateTime? endedAt,  String publisherId,  DateTime createdAt,  DateTime updatedAt,  DateTime? deletedAt)?  $default,{required TResult orElse(),}) {final _that = this;
 | 
			
		||||
switch (_that) {
 | 
			
		||||
case _SnPollWithStats() when $default != null:
 | 
			
		||||
return $default(_that.userAnswer,_that.stats,_that.id,_that.questions,_that.title,_that.description,_that.endedAt,_that.publisherId,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
 | 
			
		||||
@@ -181,7 +193,7 @@ return $default(_that.userAnswer,_that.stats,_that.id,_that.questions,_that.titl
 | 
			
		||||
/// }
 | 
			
		||||
/// ```
 | 
			
		||||
 | 
			
		||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( Map<String, dynamic>? userAnswer,  Map<String, dynamic> stats,  String id,  List<SnPollQuestion> questions,  String? title,  String? description,  DateTime? endedAt,  String publisherId,  DateTime createdAt,  DateTime updatedAt,  DateTime? deletedAt)  $default,) {final _that = this;
 | 
			
		||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( SnPollAnswer? userAnswer,  Map<String, dynamic> stats,  String id,  List<SnPollQuestion> questions,  String? title,  String? description,  DateTime? endedAt,  String publisherId,  DateTime createdAt,  DateTime updatedAt,  DateTime? deletedAt)  $default,) {final _that = this;
 | 
			
		||||
switch (_that) {
 | 
			
		||||
case _SnPollWithStats():
 | 
			
		||||
return $default(_that.userAnswer,_that.stats,_that.id,_that.questions,_that.title,_that.description,_that.endedAt,_that.publisherId,_that.createdAt,_that.updatedAt,_that.deletedAt);}
 | 
			
		||||
@@ -198,7 +210,7 @@ return $default(_that.userAnswer,_that.stats,_that.id,_that.questions,_that.titl
 | 
			
		||||
/// }
 | 
			
		||||
/// ```
 | 
			
		||||
 | 
			
		||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( Map<String, dynamic>? userAnswer,  Map<String, dynamic> stats,  String id,  List<SnPollQuestion> questions,  String? title,  String? description,  DateTime? endedAt,  String publisherId,  DateTime createdAt,  DateTime updatedAt,  DateTime? deletedAt)?  $default,) {final _that = this;
 | 
			
		||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( SnPollAnswer? userAnswer,  Map<String, dynamic> stats,  String id,  List<SnPollQuestion> questions,  String? title,  String? description,  DateTime? endedAt,  String publisherId,  DateTime createdAt,  DateTime updatedAt,  DateTime? deletedAt)?  $default,) {final _that = this;
 | 
			
		||||
switch (_that) {
 | 
			
		||||
case _SnPollWithStats() when $default != null:
 | 
			
		||||
return $default(_that.userAnswer,_that.stats,_that.id,_that.questions,_that.title,_that.description,_that.endedAt,_that.publisherId,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
 | 
			
		||||
@@ -213,18 +225,10 @@ return $default(_that.userAnswer,_that.stats,_that.id,_that.questions,_that.titl
 | 
			
		||||
@JsonSerializable()
 | 
			
		||||
 | 
			
		||||
class _SnPollWithStats implements SnPollWithStats {
 | 
			
		||||
  const _SnPollWithStats({required final  Map<String, dynamic>? userAnswer, final  Map<String, dynamic> stats = const {}, required this.id, required final  List<SnPollQuestion> questions, this.title, this.description, this.endedAt, required this.publisherId, required this.createdAt, required this.updatedAt, this.deletedAt}): _userAnswer = userAnswer,_stats = stats,_questions = questions;
 | 
			
		||||
  const _SnPollWithStats({required this.userAnswer, final  Map<String, dynamic> stats = const {}, required this.id, required final  List<SnPollQuestion> questions, this.title, this.description, this.endedAt, required this.publisherId, required this.createdAt, required this.updatedAt, this.deletedAt}): _stats = stats,_questions = questions;
 | 
			
		||||
  factory _SnPollWithStats.fromJson(Map<String, dynamic> json) => _$SnPollWithStatsFromJson(json);
 | 
			
		||||
 | 
			
		||||
 final  Map<String, dynamic>? _userAnswer;
 | 
			
		||||
@override Map<String, dynamic>? get userAnswer {
 | 
			
		||||
  final value = _userAnswer;
 | 
			
		||||
  if (value == null) return null;
 | 
			
		||||
  if (_userAnswer is EqualUnmodifiableMapView) return _userAnswer;
 | 
			
		||||
  // ignore: implicit_dynamic_type
 | 
			
		||||
  return EqualUnmodifiableMapView(value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@override final  SnPollAnswer? userAnswer;
 | 
			
		||||
 final  Map<String, dynamic> _stats;
 | 
			
		||||
@override@JsonKey() Map<String, dynamic> get stats {
 | 
			
		||||
  if (_stats is EqualUnmodifiableMapView) return _stats;
 | 
			
		||||
@@ -261,12 +265,12 @@ Map<String, dynamic> toJson() {
 | 
			
		||||
 | 
			
		||||
@override
 | 
			
		||||
bool operator ==(Object other) {
 | 
			
		||||
  return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnPollWithStats&&const DeepCollectionEquality().equals(other._userAnswer, _userAnswer)&&const DeepCollectionEquality().equals(other._stats, _stats)&&(identical(other.id, id) || other.id == id)&&const DeepCollectionEquality().equals(other._questions, _questions)&&(identical(other.title, title) || other.title == title)&&(identical(other.description, description) || other.description == description)&&(identical(other.endedAt, endedAt) || other.endedAt == endedAt)&&(identical(other.publisherId, publisherId) || other.publisherId == publisherId)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
 | 
			
		||||
  return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnPollWithStats&&(identical(other.userAnswer, userAnswer) || other.userAnswer == userAnswer)&&const DeepCollectionEquality().equals(other._stats, _stats)&&(identical(other.id, id) || other.id == id)&&const DeepCollectionEquality().equals(other._questions, _questions)&&(identical(other.title, title) || other.title == title)&&(identical(other.description, description) || other.description == description)&&(identical(other.endedAt, endedAt) || other.endedAt == endedAt)&&(identical(other.publisherId, publisherId) || other.publisherId == publisherId)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@JsonKey(includeFromJson: false, includeToJson: false)
 | 
			
		||||
@override
 | 
			
		||||
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(_userAnswer),const DeepCollectionEquality().hash(_stats),id,const DeepCollectionEquality().hash(_questions),title,description,endedAt,publisherId,createdAt,updatedAt,deletedAt);
 | 
			
		||||
int get hashCode => Object.hash(runtimeType,userAnswer,const DeepCollectionEquality().hash(_stats),id,const DeepCollectionEquality().hash(_questions),title,description,endedAt,publisherId,createdAt,updatedAt,deletedAt);
 | 
			
		||||
 | 
			
		||||
@override
 | 
			
		||||
String toString() {
 | 
			
		||||
@@ -281,11 +285,11 @@ abstract mixin class _$SnPollWithStatsCopyWith<$Res> implements $SnPollWithStats
 | 
			
		||||
  factory _$SnPollWithStatsCopyWith(_SnPollWithStats value, $Res Function(_SnPollWithStats) _then) = __$SnPollWithStatsCopyWithImpl;
 | 
			
		||||
@override @useResult
 | 
			
		||||
$Res call({
 | 
			
		||||
 Map<String, dynamic>? userAnswer, Map<String, dynamic> stats, String id, List<SnPollQuestion> questions, String? title, String? description, DateTime? endedAt, String publisherId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
 | 
			
		||||
 SnPollAnswer? userAnswer, Map<String, dynamic> stats, String id, List<SnPollQuestion> questions, String? title, String? description, DateTime? endedAt, String publisherId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@override $SnPollAnswerCopyWith<$Res>? get userAnswer;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
/// @nodoc
 | 
			
		||||
@@ -300,8 +304,8 @@ class __$SnPollWithStatsCopyWithImpl<$Res>
 | 
			
		||||
/// with the given fields replaced by the non-null parameter values.
 | 
			
		||||
@override @pragma('vm:prefer-inline') $Res call({Object? userAnswer = freezed,Object? stats = null,Object? id = null,Object? questions = null,Object? title = freezed,Object? description = freezed,Object? endedAt = freezed,Object? publisherId = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
 | 
			
		||||
  return _then(_SnPollWithStats(
 | 
			
		||||
userAnswer: freezed == userAnswer ? _self._userAnswer : userAnswer // ignore: cast_nullable_to_non_nullable
 | 
			
		||||
as Map<String, dynamic>?,stats: null == stats ? _self._stats : stats // ignore: cast_nullable_to_non_nullable
 | 
			
		||||
userAnswer: freezed == userAnswer ? _self.userAnswer : userAnswer // ignore: cast_nullable_to_non_nullable
 | 
			
		||||
as SnPollAnswer?,stats: null == stats ? _self._stats : stats // ignore: cast_nullable_to_non_nullable
 | 
			
		||||
as Map<String, dynamic>,id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
 | 
			
		||||
as String,questions: null == questions ? _self._questions : questions // ignore: cast_nullable_to_non_nullable
 | 
			
		||||
as List<SnPollQuestion>,title: freezed == title ? _self.title : title // ignore: cast_nullable_to_non_nullable
 | 
			
		||||
@@ -315,7 +319,19 @@ as DateTime?,
 | 
			
		||||
  ));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Create a copy of SnPollWithStats
 | 
			
		||||
/// with the given fields replaced by the non-null parameter values.
 | 
			
		||||
@override
 | 
			
		||||
@pragma('vm:prefer-inline')
 | 
			
		||||
$SnPollAnswerCopyWith<$Res>? get userAnswer {
 | 
			
		||||
    if (_self.userAnswer == null) {
 | 
			
		||||
    return null;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return $SnPollAnswerCopyWith<$Res>(_self.userAnswer!, (value) {
 | 
			
		||||
    return _then(_self.copyWith(userAnswer: value));
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,12 @@ part of 'poll.dart';
 | 
			
		||||
 | 
			
		||||
_SnPollWithStats _$SnPollWithStatsFromJson(Map<String, dynamic> json) =>
 | 
			
		||||
    _SnPollWithStats(
 | 
			
		||||
      userAnswer: json['user_answer'] as Map<String, dynamic>?,
 | 
			
		||||
      userAnswer:
 | 
			
		||||
          json['user_answer'] == null
 | 
			
		||||
              ? null
 | 
			
		||||
              : SnPollAnswer.fromJson(
 | 
			
		||||
                json['user_answer'] as Map<String, dynamic>,
 | 
			
		||||
              ),
 | 
			
		||||
      stats: json['stats'] as Map<String, dynamic>? ?? const {},
 | 
			
		||||
      id: json['id'] as String,
 | 
			
		||||
      questions:
 | 
			
		||||
@@ -32,7 +37,7 @@ _SnPollWithStats _$SnPollWithStatsFromJson(Map<String, dynamic> json) =>
 | 
			
		||||
 | 
			
		||||
Map<String, dynamic> _$SnPollWithStatsToJson(_SnPollWithStats instance) =>
 | 
			
		||||
    <String, dynamic>{
 | 
			
		||||
      'user_answer': instance.userAnswer,
 | 
			
		||||
      'user_answer': instance.userAnswer?.toJson(),
 | 
			
		||||
      'stats': instance.stats,
 | 
			
		||||
      'id': instance.id,
 | 
			
		||||
      'questions': instance.questions.map((e) => e.toJson()).toList(),
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@ part of 'activity_rpc.dart';
 | 
			
		||||
// **************************************************************************
 | 
			
		||||
 | 
			
		||||
String _$presenceActivitiesHash() =>
 | 
			
		||||
    r'dcea3cad01b4010c0087f5281413d83a754c2a17';
 | 
			
		||||
    r'3bfaa638eeb961ecd62a32d6a7760a6a7e7bf6f2';
 | 
			
		||||
 | 
			
		||||
/// Copied from Dart SDK
 | 
			
		||||
class _SystemHash {
 | 
			
		||||
 
 | 
			
		||||
@@ -8,11 +8,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
 | 
			
		||||
import 'package:island/screens/about.dart';
 | 
			
		||||
import 'package:island/screens/developers/app_detail.dart';
 | 
			
		||||
import 'package:island/screens/developers/bot_detail.dart';
 | 
			
		||||
import 'package:island/screens/developers/edit_app.dart';
 | 
			
		||||
import 'package:island/screens/developers/edit_bot.dart';
 | 
			
		||||
import 'package:island/screens/developers/hub.dart';
 | 
			
		||||
import 'package:island/screens/developers/new_app.dart';
 | 
			
		||||
import 'package:island/screens/developers/new_bot.dart';
 | 
			
		||||
import 'package:island/screens/developers/edit_project.dart';
 | 
			
		||||
import 'package:island/screens/developers/new_project.dart';
 | 
			
		||||
import 'package:island/screens/discovery/articles.dart';
 | 
			
		||||
@@ -570,25 +566,6 @@ final routerProvider = Provider<GoRouter>((ref) {
 | 
			
		||||
                      return const SizedBox.shrink(); // Temporary placeholder
 | 
			
		||||
                    },
 | 
			
		||||
                    routes: [
 | 
			
		||||
                      GoRoute(
 | 
			
		||||
                        name: 'developerAppNew',
 | 
			
		||||
                        path: 'apps/new',
 | 
			
		||||
                        builder:
 | 
			
		||||
                            (context, state) => NewCustomAppScreen(
 | 
			
		||||
                              publisherName: state.pathParameters['name']!,
 | 
			
		||||
                              projectId: state.pathParameters['projectId']!,
 | 
			
		||||
                            ),
 | 
			
		||||
                      ),
 | 
			
		||||
                      GoRoute(
 | 
			
		||||
                        name: 'developerAppEdit',
 | 
			
		||||
                        path: 'apps/:id/edit',
 | 
			
		||||
                        builder:
 | 
			
		||||
                            (context, state) => EditAppScreen(
 | 
			
		||||
                              publisherName: state.pathParameters['name']!,
 | 
			
		||||
                              projectId: state.pathParameters['projectId']!,
 | 
			
		||||
                              id: state.pathParameters['id']!,
 | 
			
		||||
                            ),
 | 
			
		||||
                      ),
 | 
			
		||||
                      GoRoute(
 | 
			
		||||
                        name: 'developerAppDetail',
 | 
			
		||||
                        path: 'apps/:appId',
 | 
			
		||||
@@ -599,15 +576,6 @@ final routerProvider = Provider<GoRouter>((ref) {
 | 
			
		||||
                              appId: state.pathParameters['appId']!,
 | 
			
		||||
                            ),
 | 
			
		||||
                      ),
 | 
			
		||||
                      GoRoute(
 | 
			
		||||
                        name: 'developerBotNew',
 | 
			
		||||
                        path: 'bots/new',
 | 
			
		||||
                        builder:
 | 
			
		||||
                            (context, state) => NewBotScreen(
 | 
			
		||||
                              publisherName: state.pathParameters['name']!,
 | 
			
		||||
                              projectId: state.pathParameters['projectId']!,
 | 
			
		||||
                            ),
 | 
			
		||||
                      ),
 | 
			
		||||
                      GoRoute(
 | 
			
		||||
                        name: 'developerBotDetail',
 | 
			
		||||
                        path: 'bots/:botId',
 | 
			
		||||
@@ -618,16 +586,6 @@ final routerProvider = Provider<GoRouter>((ref) {
 | 
			
		||||
                              botId: state.pathParameters['botId']!,
 | 
			
		||||
                            ),
 | 
			
		||||
                      ),
 | 
			
		||||
                      GoRoute(
 | 
			
		||||
                        name: 'developerBotEdit',
 | 
			
		||||
                        path: 'bots/:id/edit',
 | 
			
		||||
                        builder:
 | 
			
		||||
                            (context, state) => EditBotScreen(
 | 
			
		||||
                              publisherName: state.pathParameters['name']!,
 | 
			
		||||
                              projectId: state.pathParameters['projectId']!,
 | 
			
		||||
                              id: state.pathParameters['id']!,
 | 
			
		||||
                            ),
 | 
			
		||||
                      ),
 | 
			
		||||
                    ],
 | 
			
		||||
                  ),
 | 
			
		||||
                ],
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@ part of 'explore.dart';
 | 
			
		||||
// **************************************************************************
 | 
			
		||||
 | 
			
		||||
String _$activityListNotifierHash() =>
 | 
			
		||||
    r'a3ad3242f08139bef14a2f0fab6591ce8b3cb9f0';
 | 
			
		||||
    r'77ffc7852feffa5438b56fa26123d453b7c310cf';
 | 
			
		||||
 | 
			
		||||
/// Copied from Dart SDK
 | 
			
		||||
class _SystemHash {
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,6 @@ import 'dart:math' as math;
 | 
			
		||||
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:island/models/embed.dart';
 | 
			
		||||
import 'package:island/models/poll.dart';
 | 
			
		||||
import 'package:island/services/responsive.dart';
 | 
			
		||||
import 'package:island/utils/mapping.dart';
 | 
			
		||||
import 'package:island/widgets/content/embed/link.dart';
 | 
			
		||||
@@ -54,13 +53,10 @@ class EmbedListWidget extends StatelessWidget {
 | 
			
		||||
                      vertical: 8,
 | 
			
		||||
                    ),
 | 
			
		||||
                    child:
 | 
			
		||||
                        embedData['poll'] == null
 | 
			
		||||
                            ? const Text('Poll was not loaded...')
 | 
			
		||||
                        embedData['id'] == null
 | 
			
		||||
                            ? const Text('Poll was unavailable...')
 | 
			
		||||
                            : PollSubmit(
 | 
			
		||||
                              initialAnswers:
 | 
			
		||||
                                  embedData['poll']?['user_answer']?['answer'],
 | 
			
		||||
                              stats: embedData['poll']?['stats'],
 | 
			
		||||
                              poll: SnPollWithStats.fromJson(embedData['poll']),
 | 
			
		||||
                              pollId: embedData['id'],
 | 
			
		||||
                              onSubmit: (_) {},
 | 
			
		||||
                              isReadonly: !isInteractive,
 | 
			
		||||
                              isInitiallyExpanded: isFullPost,
 | 
			
		||||
 
 | 
			
		||||
@@ -4,15 +4,15 @@ import 'package:easy_localization/easy_localization.dart';
 | 
			
		||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
 | 
			
		||||
import 'package:island/models/poll.dart';
 | 
			
		||||
import 'package:island/pods/network.dart';
 | 
			
		||||
import 'package:island/screens/creators/poll/poll_list.dart';
 | 
			
		||||
import 'package:island/widgets/alert.dart';
 | 
			
		||||
import 'package:island/widgets/poll/poll_stats_widget.dart';
 | 
			
		||||
 | 
			
		||||
class PollSubmit extends ConsumerStatefulWidget {
 | 
			
		||||
  const PollSubmit({
 | 
			
		||||
    super.key,
 | 
			
		||||
    required this.poll,
 | 
			
		||||
    required this.pollId,
 | 
			
		||||
    required this.onSubmit,
 | 
			
		||||
    required this.stats,
 | 
			
		||||
    this.initialAnswers,
 | 
			
		||||
    this.onCancel,
 | 
			
		||||
    this.showProgress = true,
 | 
			
		||||
@@ -20,14 +20,13 @@ class PollSubmit extends ConsumerStatefulWidget {
 | 
			
		||||
    this.isInitiallyExpanded = false,
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  final SnPollWithStats poll;
 | 
			
		||||
  final String pollId;
 | 
			
		||||
 | 
			
		||||
  /// Callback when user submits all answers. Map questionId -> answer.
 | 
			
		||||
  final void Function(Map<String, dynamic> answers) onSubmit;
 | 
			
		||||
 | 
			
		||||
  /// Optional initial answers, keyed by questionId.
 | 
			
		||||
  final Map<String, dynamic>? initialAnswers;
 | 
			
		||||
  final Map<String, dynamic>? stats;
 | 
			
		||||
 | 
			
		||||
  /// Optional cancel callback.
 | 
			
		||||
  final VoidCallback? onCancel;
 | 
			
		||||
@@ -45,7 +44,7 @@ class PollSubmit extends ConsumerStatefulWidget {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class _PollSubmitState extends ConsumerState<PollSubmit> {
 | 
			
		||||
  late final List<SnPollQuestion> _questions;
 | 
			
		||||
  List<SnPollQuestion>? _questions;
 | 
			
		||||
  int _index = 0;
 | 
			
		||||
  bool _submitting = false;
 | 
			
		||||
  bool _isModifying = false; // New state to track if user is modifying answers
 | 
			
		||||
@@ -66,14 +65,10 @@ class _PollSubmitState extends ConsumerState<PollSubmit> {
 | 
			
		||||
  @override
 | 
			
		||||
  void initState() {
 | 
			
		||||
    super.initState();
 | 
			
		||||
    // Ensure questions are ordered by `order`
 | 
			
		||||
    _questions = [...widget.poll.questions]
 | 
			
		||||
      ..sort((a, b) => a.order.compareTo(b.order));
 | 
			
		||||
    _answers = Map<String, dynamic>.from(widget.initialAnswers ?? {});
 | 
			
		||||
    // Set initial collapse state based on the parameter
 | 
			
		||||
    _isCollapsed = !widget.isInitiallyExpanded;
 | 
			
		||||
    if (!widget.isReadonly) {
 | 
			
		||||
      _loadCurrentIntoLocalState();
 | 
			
		||||
      // If initial answers are provided, set _isModifying to false initially
 | 
			
		||||
      // so the "Modify" button is shown.
 | 
			
		||||
      if (widget.initialAnswers != null && widget.initialAnswers!.isNotEmpty) {
 | 
			
		||||
@@ -82,25 +77,27 @@ class _PollSubmitState extends ConsumerState<PollSubmit> {
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void _initializeFromPollData(SnPollWithStats poll) {
 | 
			
		||||
    // Initialize answers from poll data if available
 | 
			
		||||
    if (poll.userAnswer != null && poll.userAnswer!.answer.isNotEmpty) {
 | 
			
		||||
      _answers = Map<String, dynamic>.from(poll.userAnswer!.answer);
 | 
			
		||||
      if (!widget.isReadonly && !_isModifying) {
 | 
			
		||||
        _isModifying = false; // Show modify button if user has answered
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    _loadCurrentIntoLocalState();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  void didUpdateWidget(covariant PollSubmit oldWidget) {
 | 
			
		||||
    super.didUpdateWidget(oldWidget);
 | 
			
		||||
    if (oldWidget.poll.id != widget.poll.id) {
 | 
			
		||||
    if (oldWidget.pollId != widget.pollId) {
 | 
			
		||||
      _index = 0;
 | 
			
		||||
      _answers = Map<String, dynamic>.from(widget.initialAnswers ?? {});
 | 
			
		||||
      _questions
 | 
			
		||||
        ..clear()
 | 
			
		||||
        ..addAll(
 | 
			
		||||
          [...widget.poll.questions]
 | 
			
		||||
            ..sort((a, b) => a.order.compareTo(b.order)),
 | 
			
		||||
        );
 | 
			
		||||
      if (!widget.isReadonly) {
 | 
			
		||||
        _loadCurrentIntoLocalState();
 | 
			
		||||
        // If poll ID changes, reset modification state
 | 
			
		||||
      // Reset modification state when poll changes
 | 
			
		||||
      _isModifying = false;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  void dispose() {
 | 
			
		||||
@@ -108,7 +105,7 @@ class _PollSubmitState extends ConsumerState<PollSubmit> {
 | 
			
		||||
    super.dispose();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  SnPollQuestion get _current => _questions[_index];
 | 
			
		||||
  SnPollQuestion get _current => _questions![_index];
 | 
			
		||||
 | 
			
		||||
  void _loadCurrentIntoLocalState() {
 | 
			
		||||
    final q = _current;
 | 
			
		||||
@@ -201,7 +198,7 @@ class _PollSubmitState extends ConsumerState<PollSubmit> {
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Future<void> _submitToServer() async {
 | 
			
		||||
  Future<void> _submitToServer(SnPollWithStats poll) async {
 | 
			
		||||
    // Persist current question before final submit
 | 
			
		||||
    _persistCurrentAnswer();
 | 
			
		||||
 | 
			
		||||
@@ -213,7 +210,7 @@ class _PollSubmitState extends ConsumerState<PollSubmit> {
 | 
			
		||||
      final dio = ref.read(apiClientProvider);
 | 
			
		||||
 | 
			
		||||
      await dio.post(
 | 
			
		||||
        '/sphere/polls/${widget.poll.id}/answer',
 | 
			
		||||
        '/sphere/polls/${poll.id}/answer',
 | 
			
		||||
        data: {'answer': _answers},
 | 
			
		||||
      );
 | 
			
		||||
 | 
			
		||||
@@ -233,17 +230,17 @@ class _PollSubmitState extends ConsumerState<PollSubmit> {
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void _next() {
 | 
			
		||||
  void _next(SnPollWithStats poll) {
 | 
			
		||||
    if (_submitting) return;
 | 
			
		||||
    _persistCurrentAnswer();
 | 
			
		||||
    if (_index < _questions.length - 1) {
 | 
			
		||||
    if (_index < _questions!.length - 1) {
 | 
			
		||||
      setState(() {
 | 
			
		||||
        _index++;
 | 
			
		||||
        _loadCurrentIntoLocalState();
 | 
			
		||||
      });
 | 
			
		||||
    } else {
 | 
			
		||||
      // Final submit to API
 | 
			
		||||
      _submitToServer();
 | 
			
		||||
      _submitToServer(poll);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -261,41 +258,15 @@ class _PollSubmitState extends ConsumerState<PollSubmit> {
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Widget _buildHeader(BuildContext context) {
 | 
			
		||||
  Widget _buildHeader(BuildContext context, SnPollWithStats poll) {
 | 
			
		||||
    final q = _current;
 | 
			
		||||
    return Column(
 | 
			
		||||
      crossAxisAlignment: CrossAxisAlignment.start,
 | 
			
		||||
      children: [
 | 
			
		||||
        if (widget.poll.title != null || widget.poll.description != null)
 | 
			
		||||
          Padding(
 | 
			
		||||
            padding: const EdgeInsets.only(bottom: 12),
 | 
			
		||||
            child: Column(
 | 
			
		||||
              crossAxisAlignment: CrossAxisAlignment.start,
 | 
			
		||||
              children: [
 | 
			
		||||
                if (widget.poll.title != null)
 | 
			
		||||
                  Text(
 | 
			
		||||
                    widget.poll.title!,
 | 
			
		||||
                    style: Theme.of(context).textTheme.titleLarge,
 | 
			
		||||
                  ),
 | 
			
		||||
                if (widget.poll.description != null)
 | 
			
		||||
                  Padding(
 | 
			
		||||
                    padding: const EdgeInsets.only(top: 4),
 | 
			
		||||
                    child: Text(
 | 
			
		||||
                      widget.poll.description!,
 | 
			
		||||
                      style: Theme.of(context).textTheme.bodyMedium?.copyWith(
 | 
			
		||||
                        color: Theme.of(
 | 
			
		||||
                          context,
 | 
			
		||||
                        ).textTheme.bodyMedium?.color?.withOpacity(0.7),
 | 
			
		||||
                      ),
 | 
			
		||||
                    ),
 | 
			
		||||
                  ),
 | 
			
		||||
              ],
 | 
			
		||||
            ),
 | 
			
		||||
          ),
 | 
			
		||||
        if (widget.showProgress &&
 | 
			
		||||
            _isModifying) // Only show progress when modifying
 | 
			
		||||
          Text(
 | 
			
		||||
            '${_index + 1} / ${_questions.length}',
 | 
			
		||||
            '${_index + 1} / ${_questions!.length}',
 | 
			
		||||
            style: Theme.of(context).textTheme.labelMedium,
 | 
			
		||||
          ),
 | 
			
		||||
        Row(
 | 
			
		||||
@@ -334,12 +305,18 @@ class _PollSubmitState extends ConsumerState<PollSubmit> {
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Widget _buildStats(BuildContext context, SnPollQuestion q) {
 | 
			
		||||
    return PollStatsWidget(question: q, stats: widget.stats);
 | 
			
		||||
  Widget _buildStats(
 | 
			
		||||
    BuildContext context,
 | 
			
		||||
    SnPollQuestion q,
 | 
			
		||||
    Map<String, dynamic>? stats,
 | 
			
		||||
  ) {
 | 
			
		||||
    return PollStatsWidget(question: q, stats: stats);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Widget _buildBody(BuildContext context) {
 | 
			
		||||
    if (widget.initialAnswers != null && !widget.isReadonly && !_isModifying) {
 | 
			
		||||
  Widget _buildBody(BuildContext context, SnPollWithStats poll) {
 | 
			
		||||
    final hasUserAnswer =
 | 
			
		||||
        poll.userAnswer != null && poll.userAnswer!.answer.isNotEmpty;
 | 
			
		||||
    if (hasUserAnswer && !widget.isReadonly && !_isModifying) {
 | 
			
		||||
      return const SizedBox.shrink(); // Collapse input fields if already submitted and not modifying
 | 
			
		||||
    }
 | 
			
		||||
    final q = _current;
 | 
			
		||||
@@ -449,11 +426,13 @@ class _PollSubmitState extends ConsumerState<PollSubmit> {
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Widget _buildNavBar(BuildContext context) {
 | 
			
		||||
    final isLast = _index == _questions.length - 1;
 | 
			
		||||
  Widget _buildNavBar(BuildContext context, SnPollWithStats poll) {
 | 
			
		||||
    final isLast = _index == _questions!.length - 1;
 | 
			
		||||
    final canProceed = _isCurrentAnswered() && !_submitting;
 | 
			
		||||
    final hasUserAnswer =
 | 
			
		||||
        poll.userAnswer != null && poll.userAnswer!.answer.isNotEmpty;
 | 
			
		||||
 | 
			
		||||
    if (widget.initialAnswers != null && !_isModifying && !widget.isReadonly) {
 | 
			
		||||
    if (hasUserAnswer && !_isModifying && !widget.isReadonly) {
 | 
			
		||||
      // If poll is submitted and not in modification mode, show "Modify" button
 | 
			
		||||
      return FilledButton.icon(
 | 
			
		||||
        icon: const Icon(Icons.edit),
 | 
			
		||||
@@ -498,32 +477,32 @@ class _PollSubmitState extends ConsumerState<PollSubmit> {
 | 
			
		||||
                  )
 | 
			
		||||
                  : Icon(isLast ? Icons.check : Icons.arrow_forward),
 | 
			
		||||
          label: Text(isLast ? 'submit'.tr() : 'next'.tr()),
 | 
			
		||||
          onPressed: canProceed ? _next : null,
 | 
			
		||||
          onPressed: canProceed ? () => _next(poll) : null,
 | 
			
		||||
        ),
 | 
			
		||||
      ],
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Widget _buildSubmittedView(BuildContext context) {
 | 
			
		||||
  Widget _buildSubmittedView(BuildContext context, SnPollWithStats poll) {
 | 
			
		||||
    return Column(
 | 
			
		||||
      crossAxisAlignment: CrossAxisAlignment.start,
 | 
			
		||||
      children: [
 | 
			
		||||
        if (widget.poll.title != null || widget.poll.description != null)
 | 
			
		||||
        if (poll.title != null || poll.description != null)
 | 
			
		||||
          Padding(
 | 
			
		||||
            padding: const EdgeInsets.only(bottom: 12),
 | 
			
		||||
            child: Column(
 | 
			
		||||
              crossAxisAlignment: CrossAxisAlignment.start,
 | 
			
		||||
              children: [
 | 
			
		||||
                if (widget.poll.title?.isNotEmpty ?? false)
 | 
			
		||||
                if (poll.title?.isNotEmpty ?? false)
 | 
			
		||||
                  Text(
 | 
			
		||||
                    widget.poll.title!,
 | 
			
		||||
                    poll.title!,
 | 
			
		||||
                    style: Theme.of(context).textTheme.titleLarge,
 | 
			
		||||
                  ),
 | 
			
		||||
                if (widget.poll.description?.isNotEmpty ?? false)
 | 
			
		||||
                if (poll.description?.isNotEmpty ?? false)
 | 
			
		||||
                  Padding(
 | 
			
		||||
                    padding: const EdgeInsets.only(top: 4),
 | 
			
		||||
                    child: Text(
 | 
			
		||||
                      widget.poll.description!,
 | 
			
		||||
                      poll.description!,
 | 
			
		||||
                      style: Theme.of(context).textTheme.bodyMedium?.copyWith(
 | 
			
		||||
                        color: Theme.of(
 | 
			
		||||
                          context,
 | 
			
		||||
@@ -534,7 +513,7 @@ class _PollSubmitState extends ConsumerState<PollSubmit> {
 | 
			
		||||
              ],
 | 
			
		||||
            ),
 | 
			
		||||
          ),
 | 
			
		||||
        for (final q in _questions)
 | 
			
		||||
        for (final q in _questions!)
 | 
			
		||||
          Padding(
 | 
			
		||||
            padding: const EdgeInsets.only(bottom: 16.0),
 | 
			
		||||
            child: Column(
 | 
			
		||||
@@ -574,7 +553,7 @@ class _PollSubmitState extends ConsumerState<PollSubmit> {
 | 
			
		||||
                      ),
 | 
			
		||||
                    ),
 | 
			
		||||
                  ),
 | 
			
		||||
                _buildStats(context, q),
 | 
			
		||||
                _buildStats(context, q, poll.stats),
 | 
			
		||||
              ],
 | 
			
		||||
            ),
 | 
			
		||||
          ),
 | 
			
		||||
@@ -582,26 +561,26 @@ class _PollSubmitState extends ConsumerState<PollSubmit> {
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Widget _buildReadonlyView(BuildContext context) {
 | 
			
		||||
  Widget _buildReadonlyView(BuildContext context, SnPollWithStats poll) {
 | 
			
		||||
    return Column(
 | 
			
		||||
      crossAxisAlignment: CrossAxisAlignment.start,
 | 
			
		||||
      children: [
 | 
			
		||||
        if (widget.poll.title != null || widget.poll.description != null)
 | 
			
		||||
        if (poll.title != null || poll.description != null)
 | 
			
		||||
          Padding(
 | 
			
		||||
            padding: const EdgeInsets.only(bottom: 12),
 | 
			
		||||
            child: Column(
 | 
			
		||||
              crossAxisAlignment: CrossAxisAlignment.start,
 | 
			
		||||
              children: [
 | 
			
		||||
                if (widget.poll.title != null)
 | 
			
		||||
                if (poll.title != null)
 | 
			
		||||
                  Text(
 | 
			
		||||
                    widget.poll.title!,
 | 
			
		||||
                    poll.title!,
 | 
			
		||||
                    style: Theme.of(context).textTheme.titleLarge,
 | 
			
		||||
                  ),
 | 
			
		||||
                if (widget.poll.description != null)
 | 
			
		||||
                if (poll.description != null)
 | 
			
		||||
                  Padding(
 | 
			
		||||
                    padding: const EdgeInsets.only(top: 4),
 | 
			
		||||
                    child: Text(
 | 
			
		||||
                      widget.poll.description!,
 | 
			
		||||
                      poll.description!,
 | 
			
		||||
                      style: Theme.of(context).textTheme.bodyMedium?.copyWith(
 | 
			
		||||
                        color: Theme.of(
 | 
			
		||||
                          context,
 | 
			
		||||
@@ -612,7 +591,7 @@ class _PollSubmitState extends ConsumerState<PollSubmit> {
 | 
			
		||||
              ],
 | 
			
		||||
            ),
 | 
			
		||||
          ),
 | 
			
		||||
        for (final q in _questions)
 | 
			
		||||
        for (final q in _questions!)
 | 
			
		||||
          Padding(
 | 
			
		||||
            padding: const EdgeInsets.only(bottom: 16.0),
 | 
			
		||||
            child: Column(
 | 
			
		||||
@@ -652,7 +631,7 @@ class _PollSubmitState extends ConsumerState<PollSubmit> {
 | 
			
		||||
                      ),
 | 
			
		||||
                    ),
 | 
			
		||||
                  ),
 | 
			
		||||
                _buildStats(context, q),
 | 
			
		||||
                _buildStats(context, q, poll.stats),
 | 
			
		||||
              ],
 | 
			
		||||
            ),
 | 
			
		||||
          ),
 | 
			
		||||
@@ -660,7 +639,7 @@ class _PollSubmitState extends ConsumerState<PollSubmit> {
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Widget _buildCollapsedView(BuildContext context) {
 | 
			
		||||
  Widget _buildCollapsedView(BuildContext context, SnPollWithStats poll) {
 | 
			
		||||
    return Column(
 | 
			
		||||
      crossAxisAlignment: CrossAxisAlignment.start,
 | 
			
		||||
      children: [
 | 
			
		||||
@@ -670,20 +649,20 @@ class _PollSubmitState extends ConsumerState<PollSubmit> {
 | 
			
		||||
              child: Column(
 | 
			
		||||
                crossAxisAlignment: CrossAxisAlignment.start,
 | 
			
		||||
                children: [
 | 
			
		||||
                  if (widget.poll.title != null)
 | 
			
		||||
                  if (poll.title != null)
 | 
			
		||||
                    Text(
 | 
			
		||||
                      widget.poll.title!,
 | 
			
		||||
                      poll.title!,
 | 
			
		||||
                      style: Theme.of(context).textTheme.titleMedium?.copyWith(
 | 
			
		||||
                        fontWeight: FontWeight.w600,
 | 
			
		||||
                      ),
 | 
			
		||||
                      maxLines: 1,
 | 
			
		||||
                      overflow: TextOverflow.ellipsis,
 | 
			
		||||
                    ),
 | 
			
		||||
                  if (widget.poll.description != null)
 | 
			
		||||
                  if (poll.description != null)
 | 
			
		||||
                    Padding(
 | 
			
		||||
                      padding: const EdgeInsets.only(top: 2),
 | 
			
		||||
                      child: Text(
 | 
			
		||||
                        widget.poll.description!,
 | 
			
		||||
                        poll.description!,
 | 
			
		||||
                        style: Theme.of(context).textTheme.bodySmall?.copyWith(
 | 
			
		||||
                          color: Theme.of(
 | 
			
		||||
                            context,
 | 
			
		||||
@@ -697,7 +676,7 @@ class _PollSubmitState extends ConsumerState<PollSubmit> {
 | 
			
		||||
                    Padding(
 | 
			
		||||
                      padding: const EdgeInsets.only(top: 2),
 | 
			
		||||
                      child: Text(
 | 
			
		||||
                        '${_questions.length} question${_questions.length == 1 ? '' : 's'}',
 | 
			
		||||
                        '${_questions!.length} question${_questions!.length == 1 ? '' : 's'}',
 | 
			
		||||
                        style: Theme.of(context).textTheme.bodySmall?.copyWith(
 | 
			
		||||
                          color: Theme.of(
 | 
			
		||||
                            context,
 | 
			
		||||
@@ -729,21 +708,48 @@ class _PollSubmitState extends ConsumerState<PollSubmit> {
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    if (_questions.isEmpty) {
 | 
			
		||||
    final pollAsync = ref.watch(pollWithStatsProvider(widget.pollId));
 | 
			
		||||
 | 
			
		||||
    return pollAsync.when(
 | 
			
		||||
      loading:
 | 
			
		||||
          () => const Center(
 | 
			
		||||
            child: Padding(
 | 
			
		||||
              padding: EdgeInsets.all(16.0),
 | 
			
		||||
              child: CircularProgressIndicator(),
 | 
			
		||||
            ),
 | 
			
		||||
          ),
 | 
			
		||||
      error:
 | 
			
		||||
          (error, stack) => Center(
 | 
			
		||||
            child: Padding(
 | 
			
		||||
              padding: const EdgeInsets.all(16.0),
 | 
			
		||||
              child: Text('Failed to load poll: $error'),
 | 
			
		||||
            ),
 | 
			
		||||
          ),
 | 
			
		||||
      data: (poll) {
 | 
			
		||||
        // Initialize questions when data is available
 | 
			
		||||
        _questions = [...poll.questions]
 | 
			
		||||
          ..sort((a, b) => a.order.compareTo(b.order));
 | 
			
		||||
 | 
			
		||||
        // Initialize answers from poll data
 | 
			
		||||
        _initializeFromPollData(poll);
 | 
			
		||||
 | 
			
		||||
        if (_questions!.isEmpty) {
 | 
			
		||||
          return const SizedBox.shrink();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // If collapsed, show collapsed view for all states
 | 
			
		||||
        if (_isCollapsed) {
 | 
			
		||||
      return _buildCollapsedView(context);
 | 
			
		||||
          return _buildCollapsedView(context, poll);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // If poll is already submitted and not in readonly mode, and not in modification mode, show submitted view
 | 
			
		||||
    if (widget.initialAnswers != null && !widget.isReadonly && !_isModifying) {
 | 
			
		||||
        final hasUserAnswer =
 | 
			
		||||
            poll.userAnswer != null && poll.userAnswer!.answer.isNotEmpty;
 | 
			
		||||
        if (hasUserAnswer && !widget.isReadonly && !_isModifying) {
 | 
			
		||||
          return Column(
 | 
			
		||||
            crossAxisAlignment: CrossAxisAlignment.stretch,
 | 
			
		||||
            children: [
 | 
			
		||||
          _buildCollapsedView(context),
 | 
			
		||||
              _buildCollapsedView(context, poll),
 | 
			
		||||
              const SizedBox(height: 8),
 | 
			
		||||
              AnimatedSwitcher(
 | 
			
		||||
                duration: const Duration(milliseconds: 300),
 | 
			
		||||
@@ -751,8 +757,13 @@ class _PollSubmitState extends ConsumerState<PollSubmit> {
 | 
			
		||||
                  final offset = Tween<Offset>(
 | 
			
		||||
                    begin: const Offset(0, -0.1),
 | 
			
		||||
                    end: Offset.zero,
 | 
			
		||||
              ).animate(CurvedAnimation(parent: anim, curve: Curves.easeOut));
 | 
			
		||||
              final fade = CurvedAnimation(parent: anim, curve: Curves.easeOut);
 | 
			
		||||
                  ).animate(
 | 
			
		||||
                    CurvedAnimation(parent: anim, curve: Curves.easeOut),
 | 
			
		||||
                  );
 | 
			
		||||
                  final fade = CurvedAnimation(
 | 
			
		||||
                    parent: anim,
 | 
			
		||||
                    curve: Curves.easeOut,
 | 
			
		||||
                  );
 | 
			
		||||
                  return FadeTransition(
 | 
			
		||||
                    opacity: fade,
 | 
			
		||||
                    child: SlideTransition(position: offset, child: child),
 | 
			
		||||
@@ -761,7 +772,10 @@ class _PollSubmitState extends ConsumerState<PollSubmit> {
 | 
			
		||||
                child: Column(
 | 
			
		||||
                  key: const ValueKey('submitted_expanded'),
 | 
			
		||||
                  crossAxisAlignment: CrossAxisAlignment.stretch,
 | 
			
		||||
              children: [_buildSubmittedView(context), _buildNavBar(context)],
 | 
			
		||||
                  children: [
 | 
			
		||||
                    _buildSubmittedView(context, poll),
 | 
			
		||||
                    _buildNavBar(context, poll),
 | 
			
		||||
                  ],
 | 
			
		||||
                ),
 | 
			
		||||
              ),
 | 
			
		||||
            ],
 | 
			
		||||
@@ -773,7 +787,7 @@ class _PollSubmitState extends ConsumerState<PollSubmit> {
 | 
			
		||||
          return Column(
 | 
			
		||||
            crossAxisAlignment: CrossAxisAlignment.stretch,
 | 
			
		||||
            children: [
 | 
			
		||||
          _buildCollapsedView(context),
 | 
			
		||||
              _buildCollapsedView(context, poll),
 | 
			
		||||
              const SizedBox(height: 8),
 | 
			
		||||
              AnimatedSwitcher(
 | 
			
		||||
                duration: const Duration(milliseconds: 300),
 | 
			
		||||
@@ -781,14 +795,19 @@ class _PollSubmitState extends ConsumerState<PollSubmit> {
 | 
			
		||||
                  final offset = Tween<Offset>(
 | 
			
		||||
                    begin: const Offset(0, -0.1),
 | 
			
		||||
                    end: Offset.zero,
 | 
			
		||||
              ).animate(CurvedAnimation(parent: anim, curve: Curves.easeOut));
 | 
			
		||||
              final fade = CurvedAnimation(parent: anim, curve: Curves.easeOut);
 | 
			
		||||
                  ).animate(
 | 
			
		||||
                    CurvedAnimation(parent: anim, curve: Curves.easeOut),
 | 
			
		||||
                  );
 | 
			
		||||
                  final fade = CurvedAnimation(
 | 
			
		||||
                    parent: anim,
 | 
			
		||||
                    curve: Curves.easeOut,
 | 
			
		||||
                  );
 | 
			
		||||
                  return FadeTransition(
 | 
			
		||||
                    opacity: fade,
 | 
			
		||||
                    child: SlideTransition(position: offset, child: child),
 | 
			
		||||
                  );
 | 
			
		||||
                },
 | 
			
		||||
            child: _buildReadonlyView(context),
 | 
			
		||||
                child: _buildReadonlyView(context, poll),
 | 
			
		||||
              ),
 | 
			
		||||
            ],
 | 
			
		||||
          );
 | 
			
		||||
@@ -797,7 +816,7 @@ class _PollSubmitState extends ConsumerState<PollSubmit> {
 | 
			
		||||
        return Column(
 | 
			
		||||
          crossAxisAlignment: CrossAxisAlignment.stretch,
 | 
			
		||||
          children: [
 | 
			
		||||
        _buildCollapsedView(context),
 | 
			
		||||
            _buildCollapsedView(context, poll),
 | 
			
		||||
            const SizedBox(height: 8),
 | 
			
		||||
            AnimatedSwitcher(
 | 
			
		||||
              duration: const Duration(milliseconds: 300),
 | 
			
		||||
@@ -806,7 +825,10 @@ class _PollSubmitState extends ConsumerState<PollSubmit> {
 | 
			
		||||
                  begin: const Offset(0, -0.1),
 | 
			
		||||
                  end: Offset.zero,
 | 
			
		||||
                ).animate(CurvedAnimation(parent: anim, curve: Curves.easeOut));
 | 
			
		||||
            final fade = CurvedAnimation(parent: anim, curve: Curves.easeOut);
 | 
			
		||||
                final fade = CurvedAnimation(
 | 
			
		||||
                  parent: anim,
 | 
			
		||||
                  curve: Curves.easeOut,
 | 
			
		||||
                );
 | 
			
		||||
                return FadeTransition(
 | 
			
		||||
                  opacity: fade,
 | 
			
		||||
                  child: SlideTransition(position: offset, child: child),
 | 
			
		||||
@@ -816,25 +838,27 @@ class _PollSubmitState extends ConsumerState<PollSubmit> {
 | 
			
		||||
                key: const ValueKey('normal_expanded'),
 | 
			
		||||
                crossAxisAlignment: CrossAxisAlignment.stretch,
 | 
			
		||||
                children: [
 | 
			
		||||
              _buildHeader(context),
 | 
			
		||||
                  _buildHeader(context, poll),
 | 
			
		||||
                  const SizedBox(height: 12),
 | 
			
		||||
                  _AnimatedStep(
 | 
			
		||||
                    key: ValueKey(_current.id),
 | 
			
		||||
                    child: Column(
 | 
			
		||||
                      crossAxisAlignment: CrossAxisAlignment.stretch,
 | 
			
		||||
                      children: [
 | 
			
		||||
                    _buildBody(context),
 | 
			
		||||
                    _buildStats(context, _current),
 | 
			
		||||
                        _buildBody(context, poll),
 | 
			
		||||
                        _buildStats(context, _current, poll.stats),
 | 
			
		||||
                      ],
 | 
			
		||||
                    ),
 | 
			
		||||
                  ),
 | 
			
		||||
                  const SizedBox(height: 16),
 | 
			
		||||
              _buildNavBar(context),
 | 
			
		||||
                  _buildNavBar(context, poll),
 | 
			
		||||
                ],
 | 
			
		||||
              ),
 | 
			
		||||
            ),
 | 
			
		||||
          ],
 | 
			
		||||
        );
 | 
			
		||||
      },
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user