diff --git a/.idea/libraries/Dart_Packages.xml b/.idea/libraries/Dart_Packages.xml
index 6ad2e2b..6a4da8f 100644
--- a/.idea/libraries/Dart_Packages.xml
+++ b/.idea/libraries/Dart_Packages.xml
@@ -5,14 +5,14 @@
-
+
-
+
@@ -47,14 +47,14 @@
-
+
-
+
@@ -103,7 +103,7 @@
-
+
@@ -124,21 +124,21 @@
-
+
-
+
-
+
@@ -152,7 +152,7 @@
-
+
@@ -208,7 +208,7 @@
-
+
@@ -229,7 +229,7 @@
-
+
@@ -257,7 +257,7 @@
-
+
@@ -268,17 +268,10 @@
-
-
-
-
-
-
-
-
+
@@ -306,7 +299,7 @@
-
+
@@ -334,7 +327,7 @@
-
+
@@ -425,7 +418,7 @@
-
+
@@ -446,7 +439,7 @@
-
+
@@ -474,7 +467,7 @@
-
+
@@ -495,14 +488,14 @@
-
+
-
+
@@ -544,21 +537,21 @@
-
+
-
+
-
+
@@ -628,7 +621,7 @@
-
+
@@ -642,7 +635,7 @@
-
+
@@ -663,7 +656,7 @@
-
+
@@ -705,7 +698,7 @@
-
+
@@ -761,7 +754,7 @@
-
+
@@ -775,7 +768,7 @@
-
+
@@ -887,49 +880,49 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -964,14 +957,14 @@
-
+
-
+
@@ -992,7 +985,7 @@
-
+
@@ -1027,63 +1020,63 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -1111,7 +1104,7 @@
-
+
@@ -1132,7 +1125,7 @@
-
+
@@ -1146,7 +1139,7 @@
-
+
@@ -1174,14 +1167,14 @@
-
+
-
+
@@ -1266,30 +1259,30 @@
-
-
-
-
+
+
+
+
-
-
+
+
-
+
-
-
-
+
+
+
-
+
@@ -1297,24 +1290,23 @@
-
+
-
+
-
+
-
-
+
-
+
@@ -1325,23 +1317,23 @@
-
+
-
+
-
+
-
-
+
+
-
-
-
+
+
+
@@ -1351,12 +1343,12 @@
-
+
-
+
-
+
@@ -1369,9 +1361,9 @@
-
+
-
+
@@ -1387,48 +1379,48 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
+
+
-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
+
-
+
-
+
-
-
+
+
diff --git a/.idea/libraries/Flutter_Plugins.xml b/.idea/libraries/Flutter_Plugins.xml
index 960b61a..a5c2842 100644
--- a/.idea/libraries/Flutter_Plugins.xml
+++ b/.idea/libraries/Flutter_Plugins.xml
@@ -13,29 +13,29 @@
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/lib/api/marianumcloud/talk/getReactions/getReactions.dart b/lib/api/marianumcloud/talk/getReactions/getReactions.dart
new file mode 100644
index 0000000..815f910
--- /dev/null
+++ b/lib/api/marianumcloud/talk/getReactions/getReactions.dart
@@ -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 {
+ 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? request(Uri uri, ApiParams? body, Map? headers) {
+ return http.get(uri, headers: headers);
+ }
+
+}
\ No newline at end of file
diff --git a/lib/api/marianumcloud/talk/getReactions/getReactionsResponse.dart b/lib/api/marianumcloud/talk/getReactions/getReactionsResponse.dart
new file mode 100644
index 0000000..f316a13
--- /dev/null
+++ b/lib/api/marianumcloud/talk/getReactions/getReactionsResponse.dart
@@ -0,0 +1,31 @@
+import 'package:json_annotation/json_annotation.dart';
+
+part 'getReactionsResponse.g.dart';
+
+@JsonSerializable(explicitToJson: true)
+class GetReactionsResponse {
+ Map> data;
+
+ GetReactionsResponse(this.data);
+
+ factory GetReactionsResponse.fromJson(Map json) => _$GetReactionsResponseFromJson(json);
+ Map 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 json) => _$GetReactionsResponseObjectFromJson(json);
+ Map toJson() => _$GetReactionsResponseObjectToJson(this);
+}
+
+enum GetReactionsResponseObjectActorType {
+ @JsonValue("guests") guests,
+ @JsonValue("users") users,
+}
\ No newline at end of file
diff --git a/lib/api/marianumcloud/talk/getReactions/getReactionsResponse.g.dart b/lib/api/marianumcloud/talk/getReactions/getReactionsResponse.g.dart
new file mode 100644
index 0000000..0a122e2
--- /dev/null
+++ b/lib/api/marianumcloud/talk/getReactions/getReactionsResponse.g.dart
@@ -0,0 +1,52 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'getReactionsResponse.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+GetReactionsResponse _$GetReactionsResponseFromJson(
+ Map json) =>
+ GetReactionsResponse(
+ (json['data'] as Map).map(
+ (k, e) => MapEntry(
+ k,
+ (e as List)
+ .map((e) => GetReactionsResponseObject.fromJson(
+ e as Map))
+ .toList()),
+ ),
+ );
+
+Map _$GetReactionsResponseToJson(
+ GetReactionsResponse instance) =>
+ {
+ 'data': instance.data
+ .map((k, e) => MapEntry(k, e.map((e) => e.toJson()).toList())),
+ };
+
+GetReactionsResponseObject _$GetReactionsResponseObjectFromJson(
+ Map json) =>
+ GetReactionsResponseObject(
+ $enumDecode(
+ _$GetReactionsResponseObjectActorTypeEnumMap, json['actorType']),
+ json['actorId'] as String,
+ json['actorDisplayName'] as String,
+ json['timestamp'] as int,
+ );
+
+Map _$GetReactionsResponseObjectToJson(
+ GetReactionsResponseObject instance) =>
+ {
+ 'actorType':
+ _$GetReactionsResponseObjectActorTypeEnumMap[instance.actorType]!,
+ 'actorId': instance.actorId,
+ 'actorDisplayName': instance.actorDisplayName,
+ 'timestamp': instance.timestamp,
+ };
+
+const _$GetReactionsResponseObjectActorTypeEnumMap = {
+ GetReactionsResponseObjectActorType.guests: 'guests',
+ GetReactionsResponseObjectActorType.users: 'users',
+};
diff --git a/lib/api/marianumcloud/talk/room/getRoomResponse.g.dart b/lib/api/marianumcloud/talk/room/getRoomResponse.g.dart
index cc44798..7e2243b 100644
--- a/lib/api/marianumcloud/talk/room/getRoomResponse.g.dart
+++ b/lib/api/marianumcloud/talk/room/getRoomResponse.g.dart
@@ -53,7 +53,7 @@ GetRoomResponseObject _$GetRoomResponseObjectFromJson(
json['status'] as String?,
json['statusIcon'] as String?,
json['statusMessage'] as String?,
- );
+ )..sort = json['sort'] as String?;
Map _$GetRoomResponseObjectToJson(
GetRoomResponseObject instance) =>
@@ -90,6 +90,7 @@ Map _$GetRoomResponseObjectToJson(
'status': instance.status,
'statusIcon': instance.statusIcon,
'statusMessage': instance.statusMessage,
+ 'sort': instance.sort,
};
const _$GetRoomResponseObjectConversationTypeEnumMap = {
diff --git a/lib/view/pages/talk/chatBubble.dart b/lib/view/pages/talk/chatBubble.dart
index 9d4ef04..ba7a61e 100644
--- a/lib/view/pages/talk/chatBubble.dart
+++ b/lib/view/pages/talk/chatBubble.dart
@@ -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 {
),
],
),
+ 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(
diff --git a/lib/view/pages/talk/messageReactions.dart b/lib/view/pages/talk/messageReactions.dart
new file mode 100644
index 0000000..c1bbd7b
--- /dev/null
+++ b/lib/view/pages/talk/messageReactions.dart
@@ -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 createState() => _MessageReactionsState();
+}
+
+class _MessageReactionsState extends State {
+ late Future 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((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()
+ ],
+ );
+ },
+ ),
+ );
+ }
+}