Files
Client/lib/view/pages/talk/widgets/chat_bubble_poll.dart
T

105 lines
3.0 KiB
Dart

import 'package:flutter/material.dart';
import '../../../../api/errors/error_mapper.dart';
import '../../../../api/marianumcloud/talk/get_poll/get_poll_state.dart';
import '../../../../api/marianumcloud/talk/get_poll/get_poll_state_response.dart';
import '../../../../api/marianumcloud/talk/room/get_room_response.dart';
import '../../../../widget/details_bottom_sheet.dart';
import '../../../../widget/loading_spinner.dart';
import 'poll_options_list.dart';
/// Opens the poll bottom sheet for a Talk poll attached to a message. Loads the
/// poll state lazily; voting and closing reload the state in place and refresh
/// the chat so the surrounding message list stays in sync.
void showChatBubblePollSheet(
BuildContext context, {
required GetRoomResponseObject room,
required int pollId,
required String pollName,
required VoidCallback refetch,
}) {
showDetailsBottomSheet(
context,
header: ListTile(
leading: const Icon(Icons.poll_outlined),
title: Text(pollName, overflow: TextOverflow.ellipsis),
subtitle: const Text('Umfrage'),
),
children: (sheetCtx) => [
const SizedBox(height: 8),
_PollSheetBody(room: room, pollId: pollId, refetch: refetch),
const SizedBox(height: 16),
],
);
}
class _PollSheetBody extends StatefulWidget {
final GetRoomResponseObject room;
final int pollId;
final VoidCallback refetch;
const _PollSheetBody({
required this.room,
required this.pollId,
required this.refetch,
});
@override
State<_PollSheetBody> createState() => _PollSheetBodyState();
}
class _PollSheetBodyState extends State<_PollSheetBody> {
late Future<GetPollStateResponse> _future = _fetch();
Future<GetPollStateResponse> _fetch() =>
GetPollState(token: widget.room.token, pollId: widget.pollId).run();
void _reload() {
setState(() => _future = _fetch());
}
void _applyState(GetPollStateResponse state) {
setState(() {
// Block body: an arrow would return the Future, which setState rejects.
_future = Future.value(state);
});
widget.refetch();
}
@override
Widget build(BuildContext context) => FutureBuilder<GetPollStateResponse>(
future: _future,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Padding(
padding: EdgeInsets.all(24),
child: LoadingSpinner(),
);
}
if (snapshot.hasError) {
return Padding(
padding: const EdgeInsets.all(24),
child: Column(
children: [
Text(
errorToUserMessage(snapshot.error),
textAlign: TextAlign.center,
),
const SizedBox(height: 12),
FilledButton.tonal(
onPressed: _reload,
child: const Text('Erneut versuchen'),
),
],
),
);
}
return PollOptionsList(
pollData: snapshot.data!.data,
room: widget.room,
onStateChanged: _applyState,
);
},
);
}