implemented message forwarding and direct chat creation from group members, and added specialized share picker for forwarded content
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
import 'package:emoji_picker_flutter/emoji_picker_flutter.dart' as emojis;
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
@@ -11,9 +10,11 @@ import '../../../../api/marianumcloud/talk/room/get_room_response.dart';
|
||||
import '../../../../routing/app_routes.dart';
|
||||
import '../../../../share_intent/remote_file_ref.dart';
|
||||
import '../../../../state/app/modules/chat/bloc/chat_bloc.dart';
|
||||
import '../../../../state/app/modules/chat_list/bloc/chat_list_bloc.dart';
|
||||
import '../../../../utils/clipboard_helper.dart';
|
||||
import '../../../../widget/app_progress_indicator.dart';
|
||||
import '../../../../widget/async_action_button.dart';
|
||||
import '../../../../widget/confirm_dialog.dart';
|
||||
import '../../../../widget/debug/debug_tile.dart';
|
||||
import '../../../../widget/details_bottom_sheet.dart';
|
||||
|
||||
@@ -104,13 +105,39 @@ void showChatMessageOptionsDialog(
|
||||
);
|
||||
},
|
||||
),
|
||||
if (!kReleaseMode &&
|
||||
if (canReact && (bubbleData.message != '{file}' || attachedFile != null))
|
||||
ListTile(
|
||||
leading: const Icon(Icons.forward_outlined),
|
||||
title: const Text('Weiterleiten'),
|
||||
onTap: () {
|
||||
Navigator.of(sheetCtx).pop();
|
||||
if (!parentContext.mounted) return;
|
||||
AppRoutes.openForwardMessageToChat(
|
||||
parentContext,
|
||||
text: bubbleData.message == '{file}' ? null : bubbleData.message,
|
||||
file: attachedFile != null
|
||||
? RemoteFileRef.fromTalk(attachedFile)
|
||||
: null,
|
||||
);
|
||||
},
|
||||
),
|
||||
if (canReact &&
|
||||
!isSender &&
|
||||
chatData.type != GetRoomResponseObjectConversationType.oneToOne)
|
||||
chatData.type != GetRoomResponseObjectConversationType.oneToOne &&
|
||||
bubbleData.actorType ==
|
||||
GetRoomResponseObjectMessageActorType.user)
|
||||
ListTile(
|
||||
leading: const Icon(Icons.sms_outlined),
|
||||
title: Text("Private Nachricht an '${bubbleData.actorDisplayName}'"),
|
||||
onTap: () => Navigator.of(sheetCtx).pop(),
|
||||
title: Text('Private Nachricht an ${bubbleData.actorDisplayName}'),
|
||||
onTap: () {
|
||||
Navigator.of(sheetCtx).pop();
|
||||
if (!parentContext.mounted) return;
|
||||
_openOrCreateDirectChat(
|
||||
parentContext,
|
||||
actorId: bubbleData.actorId,
|
||||
actorDisplayName: bubbleData.actorDisplayName,
|
||||
);
|
||||
},
|
||||
),
|
||||
if (canDelete)
|
||||
AsyncListTile(
|
||||
@@ -126,6 +153,60 @@ void showChatMessageOptionsDialog(
|
||||
);
|
||||
}
|
||||
|
||||
void _openOrCreateDirectChat(
|
||||
BuildContext context, {
|
||||
required String actorId,
|
||||
required String actorDisplayName,
|
||||
}) {
|
||||
final chatListBloc = context.read<ChatListBloc>();
|
||||
|
||||
GetRoomResponseObject? findExisting() {
|
||||
final rooms = chatListBloc.state.data?.rooms;
|
||||
if (rooms == null) return null;
|
||||
for (final room in rooms.data) {
|
||||
if (room.type == GetRoomResponseObjectConversationType.oneToOne &&
|
||||
room.name == actorId) {
|
||||
return room;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
void switchToChat(GetRoomResponseObject room) {
|
||||
// Pop the current ChatView before swapping the global ChatBloc token —
|
||||
// otherwise the previous group chat stays mounted in the back-stack and
|
||||
// would render empty after a back-swipe (currentToken no longer matches).
|
||||
Navigator.of(context).popUntil((route) => route.isFirst);
|
||||
AppRoutes.openChatByToken(context, room.token);
|
||||
}
|
||||
|
||||
final existing = findExisting();
|
||||
if (existing != null) {
|
||||
switchToChat(existing);
|
||||
return;
|
||||
}
|
||||
|
||||
ConfirmDialog(
|
||||
title: 'Privatchat starten?',
|
||||
content:
|
||||
'Es existiert noch kein Privatchat mit $actorDisplayName. '
|
||||
'Soll einer erstellt werden?',
|
||||
confirmButton: 'Erstellen',
|
||||
onConfirmAsync: () async {
|
||||
await chatListBloc.createDirectChat(actorId);
|
||||
final created = findExisting();
|
||||
if (created == null) {
|
||||
throw Exception(
|
||||
'Privatchat konnte nach dem Erstellen nicht gefunden werden.',
|
||||
);
|
||||
}
|
||||
if (context.mounted) {
|
||||
switchToChat(created);
|
||||
}
|
||||
},
|
||||
).asDialog(context);
|
||||
}
|
||||
|
||||
class _ReactionsRow extends StatefulWidget {
|
||||
final String chatToken;
|
||||
final int messageId;
|
||||
|
||||
Reference in New Issue
Block a user