implemented a comprehensive Nextcloud file sharing system with support for user, group, and public link shares with gating based on server-side permissions; added sharing management interfaces including a share sheet; updated the file list with visual badges for incoming shares and improved OCS API response handling.

This commit is contained in:
2026-06-02 21:42:08 +02:00
parent b6d06dd3b4
commit baa26a6e79
33 changed files with 2453 additions and 29 deletions
+23 -3
View File
@@ -1,5 +1,6 @@
import 'package:filesize/filesize.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:nextcloud/nextcloud.dart';
import '../../../../api/marianumcloud/webdav/queries/list_files/cacheable_file.dart';
@@ -8,6 +9,7 @@ import '../../../../extensions/date_time.dart';
import '../../../../model/endpoint_data.dart';
import '../../../../routing/app_routes.dart';
import '../../../../share_intent/remote_file_ref.dart';
import '../../../../state/app/modules/nextcloud_capabilities/bloc/nextcloud_capabilities_cubit.dart';
import '../../../../utils/download_manager.dart';
import '../../../../utils/file_clipboard.dart';
import '../../../../utils/haptics.dart';
@@ -16,6 +18,7 @@ import '../../../../widget/confirm_dialog.dart';
import '../../../../widget/details_bottom_sheet.dart';
import '../../../../widget/info_dialog.dart';
import '../../talk/widgets/highlighted_linkify.dart';
import '../sharing/share_sheet.dart';
import 'file_details_sheet.dart';
import 'file_leading.dart';
@@ -329,7 +332,7 @@ class _FileElementState extends State<FileElement> {
if (!widget.file.isDirectory)
ListTile(
leading: const CenteredLeading(Icon(Icons.chat_bubble_outline)),
title: const Text('Im Talk-Chat teilen'),
title: const Text('Im Talk-Chat versenden'),
onTap: () {
Navigator.of(sheetCtx).pop();
AppRoutes.openInternalShareToChat(
@@ -338,9 +341,26 @@ class _FileElementState extends State<FileElement> {
);
},
),
if (context.read<NextcloudCapabilitiesCubit>().canShareAtAll)
ListTile(
leading: const CenteredLeading(Icon(Icons.person_add_outlined)),
title: const Text('Freigeben'),
onTap: () {
Navigator.of(sheetCtx).pop();
showShareSheet(context, widget.file);
},
),
ListTile(
leading: const CenteredLeading(Icon(Icons.delete_outline)),
title: const Text('Löschen'),
leading: CenteredLeading(
Icon(
Icons.delete_outline,
color: Theme.of(sheetCtx).colorScheme.error,
),
),
title: Text(
'Löschen',
style: TextStyle(color: Theme.of(sheetCtx).colorScheme.error),
),
onTap: () {
Navigator.of(sheetCtx).pop();
_delete();
+27 -1
View File
@@ -23,7 +23,7 @@ class FileLeading extends StatelessWidget {
Widget build(BuildContext context) {
final icon = Icon(iconForFile(file), size: size);
final fileId = file.fileId;
return SizedBox(
final base = SizedBox(
width: size,
height: size,
child: (file.isDirectory || file.hasPreview != true || fileId == null)
@@ -47,5 +47,31 @@ class FileLeading extends StatelessWidget {
),
),
);
// Badge incoming shares (shared with the user by someone else).
if (file.isSharedWithMe != true) return base;
final colors = Theme.of(context).colorScheme;
return Stack(
clipBehavior: Clip.none,
children: [
base,
Positioned(
right: -3,
bottom: -3,
child: Container(
decoration: BoxDecoration(
color: colors.errorContainer,
shape: BoxShape.circle,
),
padding: const EdgeInsets.all(1),
child: Icon(
Icons.people,
size: size * 0.45,
color: colors.onErrorContainer,
),
),
),
],
);
}
}