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

113 lines
3.2 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 void Function({bool renew}) 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 void Function({bool renew}) refetch;
const _PollSheetBody({
required this.room,
required this.pollId,
required this.refetch,
});
@override
State<_PollSheetBody> createState() => _PollSheetBodyState();
}
class _PollSheetBodyState extends State<_PollSheetBody> {
Future<GetPollStateResponse>? _future;
@override
void initState() {
super.initState();
_future = GetPollState(token: widget.room.token, pollId: widget.pollId).run();
}
void _reload() {
setState(() {
_future = GetPollState(
token: widget.room.token,
pollId: widget.pollId,
).run();
});
}
void _applyState(GetPollStateResponse state) {
setState(() {
// Block body: an arrow would return the Future, which setState rejects.
_future = Future.value(state);
});
widget.refetch(renew: true);
}
@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,
);
},
);
}