113 lines
3.2 KiB
Dart
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,
|
|
);
|
|
},
|
|
);
|
|
}
|