implemented message forwarding and direct chat creation from group members, and added specialized share picker for forwarded content

This commit is contained in:
2026-05-09 20:39:19 +02:00
parent 151678f0fe
commit b422430994
3 changed files with 150 additions and 5 deletions
@@ -7,6 +7,8 @@ import 'package:persistent_bottom_nav_bar_v2/persistent_bottom_nav_bar_v2.dart';
import '../../../api/errors/error_mapper.dart';
import '../../../api/marianumcloud/talk/room/get_room_response.dart';
import '../../../api/marianumcloud/talk/send_message/send_message.dart';
import '../../../api/marianumcloud/talk/send_message/send_message_params.dart';
import '../../../api/marianumcloud/talk/share_files_to_chat.dart';
import '../../../api/marianumcloud/webdav/webdav_api.dart';
import '../../../routing/app_routes.dart';
@@ -47,6 +49,23 @@ class ShareChatPicker extends StatelessWidget {
onPicked: (ctx, room) => _internalShareFlow(ctx, room, file),
);
/// Forward an existing Talk message (text and/or already-uploaded file
/// attachment) into another chat. The attachment is re-shared via the same
/// FileSharingApi path used for [forInternalShare]; plain text is posted
/// with [SendMessage].
factory ShareChatPicker.forMessageForward({
String? text,
RemoteFileRef? file,
}) {
assert(
text != null || file != null,
'forMessageForward requires either text or file',
);
return ShareChatPicker._(
onPicked: (ctx, room) => _forwardMessageFlow(ctx, room, text, file),
);
}
@override
Widget build(BuildContext context) {
final talkSettings = context.watch<SettingsCubit>().val().talkSettings;
@@ -217,6 +236,39 @@ Future<void> _internalShareFlow(
_finishWithChat(context, room);
}
Future<void> _forwardMessageFlow(
BuildContext context,
GetRoomResponseObject room,
String? text,
RemoteFileRef? file,
) async {
unawaited(_showBlockingSpinner(context));
try {
if (file != null) {
await shareFilesToChat(
token: room.token,
remoteFilePaths: [file.path],
);
}
if (text != null && text.isNotEmpty) {
await SendMessage(room.token, SendMessageParams(text)).run();
}
} catch (e) {
if (context.mounted) Navigator.of(context).pop();
if (context.mounted) {
InfoDialog.show(
context,
errorToUserMessage(e),
title: 'Fehler',
copyable: true,
);
}
return;
}
if (!context.mounted) return;
_finishWithChat(context, room);
}
/// Modal progress overlay shown during share-API roundtrips. The dialog is
/// popped together with the picker by the subsequent popUntil(isFirst).
Future<void> _showBlockingSpinner(BuildContext context) => showDialog<void>(