implemented native share intent support for android and ios with chat and folder pickers

This commit is contained in:
2026-05-09 19:42:51 +02:00
parent 00664c66a8
commit cb2c38aaa1
25 changed files with 1046 additions and 26 deletions
+7 -2
View File
@@ -5,8 +5,9 @@ import 'widgets/chat_tile.dart';
class SearchChat extends SearchDelegate<GetRoomResponseObject?> {
List<GetRoomResponseObject> chats;
final void Function(GetRoomResponseObject room)? onTapOverride;
SearchChat(this.chats);
SearchChat(this.chats, {this.onTapOverride});
@override
List<Widget>? buildActions(BuildContext context) => [
@@ -34,7 +35,11 @@ class SearchChat extends SearchDelegate<GetRoomResponseObject?> {
itemCount: items.length,
itemBuilder: (context, index) {
var item = items.elementAt(index);
return ChatTile(data: item, disableContextActions: true);
return ChatTile(
data: item,
disableContextActions: true,
onTapOverride: onTapOverride,
);
},
);
}
+11 -22
View File
@@ -1,15 +1,13 @@
import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:nextcloud/nextcloud.dart';
import 'package:persistent_bottom_nav_bar_v2/persistent_bottom_nav_bar_v2.dart';
import '../../../../api/marianumcloud/files_sharing/file_sharing_api.dart';
import '../../../../api/marianumcloud/files_sharing/file_sharing_api_params.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 '../../../../state/app/modules/chat/bloc/chat_bloc.dart';
import '../../../../state/app/modules/settings/bloc/settings_cubit.dart';
@@ -36,30 +34,21 @@ class _ChatTextfieldState extends State<ChatTextfield> {
final AsyncActionController _sendController = AsyncActionController();
String? _sendError;
void share(String shareFolder, List<String> filePaths) {
for (final element in filePaths) {
final fileName = element.split(Platform.pathSeparator).last;
FileSharingApi()
.share(
FileSharingApiParams(
shareType: 10,
shareWith: widget.sendToToken,
path: '$shareFolder/$fileName',
),
)
.then((_) {
if (mounted) context.read<ChatBloc>().refresh();
});
}
void share(List<String> uploadedRemotePaths) {
shareFilesToChat(
token: widget.sendToToken,
remoteFilePaths: uploadedRemotePaths,
).then((_) {
if (mounted) context.read<ChatBloc>().refresh();
});
}
Future<void> mediaUpload(List<String>? paths) async {
if (paths == null) return;
const shareFolder = 'MarianumMobile';
unawaited(
WebdavApi.webdav.then(
(webdav) => webdav.mkcol(PathUri.parse('/$shareFolder')),
(webdav) => webdav.mkcol(PathUri.parse('/$talkShareFolder')),
),
);
@@ -70,8 +59,8 @@ class _ChatTextfieldState extends State<ChatTextfield> {
withNavBar: false,
screen: FilesUploadDialog(
filePaths: paths,
remotePath: shareFolder,
onUploadFinished: (uploaded) => share(shareFolder, uploaded),
remotePath: talkShareFolder,
onUploadFinished: share,
uniqueNames: true,
),
),
@@ -25,11 +25,17 @@ class ChatTile extends StatefulWidget {
final bool disableContextActions;
final bool hasDraft;
/// When set, replaces the default tap-into-chat behaviour. Used by the
/// share-intent picker to surface the room selection without opening the
/// chat view itself.
final void Function(GetRoomResponseObject room)? onTapOverride;
const ChatTile({
super.key,
required this.data,
this.disableContextActions = false,
this.hasDraft = false,
this.onTapOverride,
});
@override
@@ -143,6 +149,10 @@ class _ChatTileState extends State<ChatTile> {
),
),
onTap: () {
if (widget.onTapOverride != null) {
widget.onTapOverride!(widget.data);
return;
}
if (selfUsername == null) return;
unawaited(_setCurrentAsRead());
final view = ChatView(