refactored broad range of the application, split files, modularized calendar and file views, centralized bottom sheets and clipboard handling, and implemented unit test coverage
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../../../api/marianumcloud/talk/chat/get_chat_response.dart';
|
||||
import '../../../../api/marianumcloud/talk/delete_react_message/delete_react_message.dart';
|
||||
import '../../../../api/marianumcloud/talk/delete_react_message/delete_react_message_params.dart';
|
||||
import '../../../../api/marianumcloud/talk/react_message/react_message.dart';
|
||||
import '../../../../api/marianumcloud/talk/react_message/react_message_params.dart';
|
||||
import '../../../../api/marianumcloud/talk/room/get_room_response.dart';
|
||||
import '../../../../widget/async_action_button.dart';
|
||||
|
||||
/// Reactions wrap shown beneath a chat bubble. Tapping a reaction toggles
|
||||
/// the user's own reaction via the Talk API and notifies via [onChanged].
|
||||
class ChatBubbleReactions extends StatelessWidget {
|
||||
final GetChatResponseObject bubbleData;
|
||||
final GetRoomResponseObject chatData;
|
||||
final bool isSender;
|
||||
final void Function({bool renew}) onChanged;
|
||||
|
||||
const ChatBubbleReactions({
|
||||
required this.bubbleData,
|
||||
required this.chatData,
|
||||
required this.isSender,
|
||||
required this.onChanged,
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final reactions = bubbleData.reactions;
|
||||
if (reactions == null) return const SizedBox.shrink();
|
||||
return Transform.translate(
|
||||
offset: const Offset(0, -10),
|
||||
child: Container(
|
||||
width: MediaQuery.of(context).size.width,
|
||||
margin: const EdgeInsets.only(left: 15, right: 15),
|
||||
child: Wrap(
|
||||
alignment: isSender ? WrapAlignment.end : WrapAlignment.start,
|
||||
crossAxisAlignment: WrapCrossAlignment.start,
|
||||
children: reactions.entries.map<Widget>((e) {
|
||||
final hasSelfReacted = bubbleData.reactionsSelf?.contains(e.key) ?? false;
|
||||
return Container(
|
||||
margin: const EdgeInsets.only(right: 2.5, left: 2.5),
|
||||
child: ActionChip(
|
||||
label: Text('${e.key} ${e.value}'),
|
||||
visualDensity: const VisualDensity(vertical: VisualDensity.minimumDensity, horizontal: VisualDensity.minimumDensity),
|
||||
padding: EdgeInsets.zero,
|
||||
backgroundColor: hasSelfReacted ? Theme.of(context).primaryColor : null,
|
||||
onPressed: () {
|
||||
runWithErrorDialog(context, () async {
|
||||
if (hasSelfReacted) {
|
||||
await DeleteReactMessage(
|
||||
chatToken: chatData.token,
|
||||
messageId: bubbleData.id,
|
||||
params: DeleteReactMessageParams(e.key),
|
||||
).run();
|
||||
} else {
|
||||
await ReactMessage(
|
||||
chatToken: chatData.token,
|
||||
messageId: bubbleData.id,
|
||||
params: ReactMessageParams(e.key),
|
||||
).run();
|
||||
}
|
||||
onChanged(renew: true);
|
||||
});
|
||||
},
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user