Added reaction overview with list of names who reacted
This commit is contained in:
27
lib/api/marianumcloud/talk/getReactions/getReactions.dart
Normal file
27
lib/api/marianumcloud/talk/getReactions/getReactions.dart
Normal file
@ -0,0 +1,27 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:http/http.dart';
|
||||
|
||||
import '../../../apiParams.dart';
|
||||
import '../talkApi.dart';
|
||||
import 'getReactionsResponse.dart';
|
||||
|
||||
class GetReactions extends TalkApi<GetReactionsResponse> {
|
||||
String chatToken;
|
||||
int messageId;
|
||||
GetReactions({required this.chatToken, required this.messageId}) : super("v1/reaction/$chatToken/$messageId", null);
|
||||
|
||||
@override
|
||||
assemble(String raw) {
|
||||
log(raw);
|
||||
return GetReactionsResponse.fromJson(jsonDecode(raw)['ocs']);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Response>? request(Uri uri, ApiParams? body, Map<String, String>? headers) {
|
||||
return http.get(uri, headers: headers);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
part 'getReactionsResponse.g.dart';
|
||||
|
||||
@JsonSerializable(explicitToJson: true)
|
||||
class GetReactionsResponse {
|
||||
Map<String, List<GetReactionsResponseObject>> data;
|
||||
|
||||
GetReactionsResponse(this.data);
|
||||
|
||||
factory GetReactionsResponse.fromJson(Map<String, dynamic> json) => _$GetReactionsResponseFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$GetReactionsResponseToJson(this);
|
||||
}
|
||||
|
||||
@JsonSerializable()
|
||||
class GetReactionsResponseObject {
|
||||
GetReactionsResponseObjectActorType actorType;
|
||||
String actorId;
|
||||
String actorDisplayName;
|
||||
int timestamp;
|
||||
|
||||
GetReactionsResponseObject(this.actorType, this.actorId, this.actorDisplayName, this.timestamp);
|
||||
|
||||
factory GetReactionsResponseObject.fromJson(Map<String, dynamic> json) => _$GetReactionsResponseObjectFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$GetReactionsResponseObjectToJson(this);
|
||||
}
|
||||
|
||||
enum GetReactionsResponseObjectActorType {
|
||||
@JsonValue("guests") guests,
|
||||
@JsonValue("users") users,
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'getReactionsResponse.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
GetReactionsResponse _$GetReactionsResponseFromJson(
|
||||
Map<String, dynamic> json) =>
|
||||
GetReactionsResponse(
|
||||
(json['data'] as Map<String, dynamic>).map(
|
||||
(k, e) => MapEntry(
|
||||
k,
|
||||
(e as List<dynamic>)
|
||||
.map((e) => GetReactionsResponseObject.fromJson(
|
||||
e as Map<String, dynamic>))
|
||||
.toList()),
|
||||
),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$GetReactionsResponseToJson(
|
||||
GetReactionsResponse instance) =>
|
||||
<String, dynamic>{
|
||||
'data': instance.data
|
||||
.map((k, e) => MapEntry(k, e.map((e) => e.toJson()).toList())),
|
||||
};
|
||||
|
||||
GetReactionsResponseObject _$GetReactionsResponseObjectFromJson(
|
||||
Map<String, dynamic> json) =>
|
||||
GetReactionsResponseObject(
|
||||
$enumDecode(
|
||||
_$GetReactionsResponseObjectActorTypeEnumMap, json['actorType']),
|
||||
json['actorId'] as String,
|
||||
json['actorDisplayName'] as String,
|
||||
json['timestamp'] as int,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$GetReactionsResponseObjectToJson(
|
||||
GetReactionsResponseObject instance) =>
|
||||
<String, dynamic>{
|
||||
'actorType':
|
||||
_$GetReactionsResponseObjectActorTypeEnumMap[instance.actorType]!,
|
||||
'actorId': instance.actorId,
|
||||
'actorDisplayName': instance.actorDisplayName,
|
||||
'timestamp': instance.timestamp,
|
||||
};
|
||||
|
||||
const _$GetReactionsResponseObjectActorTypeEnumMap = {
|
||||
GetReactionsResponseObjectActorType.guests: 'guests',
|
||||
GetReactionsResponseObjectActorType.users: 'users',
|
||||
};
|
@ -53,7 +53,7 @@ GetRoomResponseObject _$GetRoomResponseObjectFromJson(
|
||||
json['status'] as String?,
|
||||
json['statusIcon'] as String?,
|
||||
json['statusMessage'] as String?,
|
||||
);
|
||||
)..sort = json['sort'] as String?;
|
||||
|
||||
Map<String, dynamic> _$GetRoomResponseObjectToJson(
|
||||
GetRoomResponseObject instance) =>
|
||||
@ -90,6 +90,7 @@ Map<String, dynamic> _$GetRoomResponseObjectToJson(
|
||||
'status': instance.status,
|
||||
'statusIcon': instance.statusIcon,
|
||||
'statusMessage': instance.statusMessage,
|
||||
'sort': instance.sort,
|
||||
};
|
||||
|
||||
const _$GetRoomResponseObjectConversationTypeEnumMap = {
|
||||
|
@ -18,6 +18,7 @@ import '../../../theming/appTheme.dart';
|
||||
import '../../../widget/debug/debugTile.dart';
|
||||
import '../files/fileElement.dart';
|
||||
import 'chatMessage.dart';
|
||||
import 'messageReactions.dart';
|
||||
|
||||
class ChatBubble extends StatefulWidget {
|
||||
final BuildContext context;
|
||||
@ -199,6 +200,20 @@ class _ChatBubbleState extends State<ChatBubble> {
|
||||
),
|
||||
],
|
||||
),
|
||||
const Divider(),
|
||||
Visibility(
|
||||
visible: true,
|
||||
child: ListTile(
|
||||
leading: const Icon(Icons.add_reaction_outlined),
|
||||
title: const Text("Reaktionen"),
|
||||
onTap: () {
|
||||
Navigator.of(context).push(MaterialPageRoute(builder: (context) => MessageReactions(
|
||||
token: widget.chatData.token,
|
||||
messageId: widget.bubbleData.id,
|
||||
)));
|
||||
},
|
||||
),
|
||||
),
|
||||
Visibility(
|
||||
visible: !message.containsFile && widget.bubbleData.messageType == GetRoomResponseObjectMessageType.comment,
|
||||
child: ListTile(
|
||||
|
73
lib/view/pages/talk/messageReactions.dart
Normal file
73
lib/view/pages/talk/messageReactions.dart
Normal file
@ -0,0 +1,73 @@
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../../api/marianumcloud/talk/getReactions/getReactions.dart';
|
||||
import '../../../api/marianumcloud/talk/getReactions/getReactionsResponse.dart';
|
||||
import '../../../model/accountData.dart';
|
||||
import '../../../widget/centeredLeading.dart';
|
||||
import '../../../widget/loadingSpinner.dart';
|
||||
import '../../../widget/unimplementedDialog.dart';
|
||||
|
||||
class MessageReactions extends StatefulWidget {
|
||||
final String token;
|
||||
final int messageId;
|
||||
const MessageReactions({super.key, required this.token, required this.messageId});
|
||||
|
||||
@override
|
||||
State<MessageReactions> createState() => _MessageReactionsState();
|
||||
}
|
||||
|
||||
class _MessageReactionsState extends State<MessageReactions> {
|
||||
late Future<GetReactionsResponse> data;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
data = GetReactions(chatToken: widget.token, messageId: widget.messageId).run();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text("Reaktionen"),
|
||||
),
|
||||
body: FutureBuilder(
|
||||
future: data,
|
||||
builder: (context, snapshot) {
|
||||
if(snapshot.data == null) return const LoadingSpinner();
|
||||
log(snapshot.data!.toJson().toString());
|
||||
return ListView(
|
||||
children: [
|
||||
...snapshot.data!.data.entries.map<Widget>((entry) {
|
||||
return ExpansionTile(
|
||||
textColor: Theme.of(context).colorScheme.onSurface,
|
||||
collapsedTextColor: Theme.of(context).colorScheme.onSurface,
|
||||
iconColor: Theme.of(context).colorScheme.onSurface,
|
||||
collapsedIconColor: Theme.of(context).colorScheme.onSurface,
|
||||
|
||||
subtitle: const Text("Tippe für mehr"),
|
||||
leading: Text(entry.key),
|
||||
title: Text("${entry.value.length} mal reagiert"),
|
||||
children: entry.value.map((e) {
|
||||
bool isSelf = AccountData().getUsername() == e.actorId;
|
||||
return ListTile(
|
||||
leading: const CenteredLeading(Icon(Icons.person)),
|
||||
title: Text(e.actorDisplayName),
|
||||
subtitle: isSelf ? const Text("Du") : e.actorType == GetReactionsResponseObjectActorType.guests ? const Text("Gast") : null,
|
||||
trailing: isSelf ? null : IconButton(
|
||||
onPressed: () => UnimplementedDialog.show(context),
|
||||
icon: const Icon(Icons.textsms_outlined),
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
);
|
||||
}).toList()
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user