List files shared with you in Sharing

This commit is contained in:
Ming Ming 2021-10-12 01:03:37 +08:00
parent 50ba293345
commit afd859d414
8 changed files with 108 additions and 19 deletions

View file

@ -538,10 +538,12 @@ class _OcsFilesSharingShares {
/// Get Shares from a specific file or folder
///
/// See: https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-share-api.html#get-shares-from-a-specific-file-or-folder
/// See: https://doc.owncloud.com/server/latest/developer_manual/core/apis/ocs-share-api.html#get-all-shares
Future<Response> get({
String? path,
bool? reshares,
bool? subfiles,
bool? sharedWithMe,
}) async {
try {
return await _filesSharing._ocs._api.request(
@ -555,6 +557,7 @@ class _OcsFilesSharingShares {
if (path != null) "path": path,
if (reshares != null) "reshares": reshares.toString(),
if (subfiles != null) "subfiles": subfiles.toString(),
if (sharedWithMe != null) "shared_with_me": sharedWithMe.toString(),
},
);
} catch (e) {

View file

@ -174,6 +174,15 @@ class ListSharingBloc extends Bloc<ListSharingBlocEvent, ListSharingBlocState> {
}
Future<List<ListSharingItem>> _query(ListSharingBlocQuery ev) async {
return (await Future.wait([
_querySharesByMe(ev),
_querySharesWithMe(ev),
]))
.reduce((value, element) => value + element);
}
Future<List<ListSharingItem>> _querySharesByMe(
ListSharingBlocQuery ev) async {
final shareRepo = ShareRepo(ShareRemoteDataSource());
final shares = await shareRepo.listAll(ev.account);
final futures = shares.map((e) async {
@ -206,7 +215,32 @@ class ListSharingBloc extends Bloc<ListSharingBlocEvent, ListSharingBlocState> {
final file = await FindFile()(ev.account, e.itemSource);
return ListSharingItem(e, file);
} catch (_) {
_log.warning("[_query] File not found: ${e.itemSource}");
_log.warning("[_querySharesByMe] File not found: ${e.itemSource}");
return null;
}
});
return (await Future.wait(futures)).whereType<ListSharingItem>().toList();
}
Future<List<ListSharingItem>> _querySharesWithMe(
ListSharingBlocQuery ev) async {
final shareRepo = ShareRepo(ShareRemoteDataSource());
final shares = await shareRepo.reverseListAll(ev.account);
final futures = shares.map((e) async {
if (!file_util.isSupportedMime(e.mimeType)) {
return null;
}
if (ev.account.roots
.every((r) => r.isNotEmpty && !e.path.startsWith("/$r/"))) {
// ignore files not under root dirs
return null;
}
try {
final file = await FindFile()(ev.account, e.itemSource);
return ListSharingItem(e, file);
} catch (_) {
_log.warning("[_querySharesWithMe] File not found: ${e.itemSource}");
return null;
}
});

View file

@ -88,6 +88,8 @@ class Share with EquatableMixin {
required this.id,
required this.shareType,
required this.stime,
required this.uidOwner,
required this.displaynameOwner,
required String path,
required this.itemType,
required this.mimeType,
@ -103,6 +105,8 @@ class Share with EquatableMixin {
"id: $id, "
"shareType: $shareType, "
"stime: $stime, "
"uidOwner: $uidOwner, "
"displaynameOwner: $displaynameOwner, "
"path: $path, "
"itemType: $itemType, "
"mimeType: $mimeType, "
@ -118,6 +122,8 @@ class Share with EquatableMixin {
id,
shareType,
stime,
uidOwner,
displaynameOwner,
path,
itemType,
mimeType,
@ -131,6 +137,8 @@ class Share with EquatableMixin {
final String id;
final ShareType shareType;
final DateTime stime;
final String uidOwner;
final String displaynameOwner;
final String path;
final ShareItemType itemType;
final String mimeType;
@ -158,6 +166,10 @@ class ShareRepo {
/// See [ShareDataSource.listAll]
Future<List<Share>> listAll(Account account) => dataSrc.listAll(account);
/// See [ShareDataSource.reverseListAll]
Future<List<Share>> reverseListAll(Account account) =>
dataSrc.reverseListAll(account);
/// See [ShareDataSource.create]
Future<Share> create(Account account, File file, String shareWith) =>
dataSrc.create(account, file, shareWith);
@ -187,6 +199,9 @@ abstract class ShareDataSource {
/// List all shares from a given user
Future<List<Share>> listAll(Account account);
/// List all shares by other users with a given user
Future<List<Share>> reverseListAll(Account account);
/// Share a file/folder with a user
Future<Share> create(Account account, File file, String shareWith);

View file

@ -6,6 +6,7 @@ import 'package:nc_photos/api/api.dart';
import 'package:nc_photos/entity/file.dart';
import 'package:nc_photos/entity/share.dart';
import 'package:nc_photos/exception.dart';
import 'package:nc_photos/iterable_extension.dart';
import 'package:nc_photos/type.dart';
class ShareRemoteDataSource implements ShareDataSource {
@ -35,6 +36,15 @@ class ShareRemoteDataSource implements ShareDataSource {
return _onListResult(response);
}
@override
reverseListAll(Account account) async {
_log.info("[reverseListAll] $account");
final response = await Api(account).ocs().filesSharing().shares().get(
sharedWithMe: true,
);
return _onListResult(response);
}
@override
create(Account account, File file, String shareWith) async {
_log.info("[create] Share '${file.path}' with '$shareWith'");
@ -127,8 +137,9 @@ class _ShareParser {
return Share(
id: json["id"],
shareType: shareType,
stime:
DateTime.fromMillisecondsSinceEpoch(json["stime"] * 1000),
stime: DateTime.fromMillisecondsSinceEpoch(json["stime"] * 1000),
uidOwner: json["uid_owner"],
displaynameOwner: json["displayname_owner"],
path: json["path"],
itemType: itemType,
mimeType: json["mimetype"],

View file

@ -869,6 +869,19 @@
}
}
},
"fileLastSharedByOthersDescription": "{user} shared with you on {date}",
"@fileLastSharedByOthersDescription": {
"description": "The date when this file was shared with you",
"placeholders": {
"user": {
"example": "Alice"
},
"date": {
"example": "Jan 1, 2021",
"description": "The date string is formatted according to the current locale"
}
}
},
"sharedWithLabel": "Shared with",
"@sharedWithLabel": {
"description": "A list of users or links where this file is sharing with"

View file

@ -8,6 +8,7 @@
"sortOptionManualLabel",
"collectionSharingLabel",
"fileLastSharedDescription",
"fileLastSharedByOthersDescription",
"sharedWithLabel",
"unshareTooltip",
"unshareSuccessNotification",
@ -45,6 +46,7 @@
"shareMethodPasswordLinkDescription",
"collectionSharingLabel",
"fileLastSharedDescription",
"fileLastSharedByOthersDescription",
"sharedWithLabel",
"unshareTooltip",
"unshareSuccessNotification",
@ -137,6 +139,7 @@
"shareMethodPasswordLinkDescription",
"collectionSharingLabel",
"fileLastSharedDescription",
"fileLastSharedByOthersDescription",
"sharedWithLabel",
"unshareTooltip",
"unshareSuccessNotification",
@ -160,6 +163,7 @@
"sortOptionManualLabel",
"collectionSharingLabel",
"fileLastSharedDescription",
"fileLastSharedByOthersDescription",
"sharedWithLabel",
"unshareTooltip",
"unshareSuccessNotification",
@ -232,6 +236,7 @@
"shareMethodPasswordLinkDescription",
"collectionSharingLabel",
"fileLastSharedDescription",
"fileLastSharedByOthersDescription",
"sharedWithLabel",
"unshareTooltip",
"unshareSuccessNotification",
@ -277,6 +282,7 @@
"shareMethodPasswordLinkDescription",
"collectionSharingLabel",
"fileLastSharedDescription",
"fileLastSharedByOthersDescription",
"sharedWithLabel",
"unshareTooltip",
"unshareSuccessNotification",

View file

@ -127,23 +127,25 @@ class _SharedFileViewerState extends State<SharedFileViewer> {
title: Text(widget.file.strippedPath),
),
),
SliverToBoxAdapter(
child: Padding(
padding: const EdgeInsets.all(16),
child: Text(
L10n.global().sharedWithLabel,
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
if (widget.shares.first.uidOwner == widget.account.username) ...[
SliverToBoxAdapter(
child: Padding(
padding: const EdgeInsets.all(16),
child: Text(
L10n.global().sharedWithLabel,
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
),
),
),
),
),
SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) => _buildShareItem(context, _shares[index]),
childCount: _shares.length,
SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) => _buildShareItem(context, _shares[index]),
childCount: _shares.length,
),
),
),
],
],
);
}

View file

@ -201,7 +201,10 @@ class _SharingBrowserState extends State<SharingBrowser> {
overflow: TextOverflow.ellipsis,
),
Text(
L10n.global().fileLastSharedDescription(dateStr),
shares.first.share.uidOwner == widget.account.username
? L10n.global().fileLastSharedDescription(dateStr)
: L10n.global().fileLastSharedByOthersDescription(
shares.first.share.displaynameOwner, dateStr),
style: TextStyle(
color: AppTheme.getSecondaryTextColor(context),
),
@ -238,8 +241,10 @@ class _SharingBrowserState extends State<SharingBrowser> {
// group shares of the same file
final map = <String, List<ListSharingItem>>{};
for (final i in items) {
map[i.share.path] ??= <ListSharingItem>[];
map[i.share.path]!.add(i);
final isSharedByMe = i.share.uidOwner == widget.account.username;
final groupKey = "${i.share.path}?$isSharedByMe";
map[groupKey] ??= <ListSharingItem>[];
map[groupKey]!.add(i);
}
// sort the sub-lists
for (final list in map.values) {