mirror of
https://gitlab.com/nkming2/nc-photos.git
synced 2025-02-24 18:38:48 +01:00
(Un)Share associated files when (un)sharing an album
This commit is contained in:
parent
b533c9caf7
commit
5b1dcfb515
8 changed files with 387 additions and 51 deletions
|
@ -40,4 +40,6 @@ class LogCapturer {
|
|||
static LogCapturer? _inst;
|
||||
}
|
||||
|
||||
String logFilename(String filename) => shouldLogFileName ? filename : "***";
|
||||
|
||||
const bool shouldLogFileName = kDebugMode;
|
||||
|
|
|
@ -971,6 +971,42 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"shareAlbumSuccessNotification": "Album shared with {user}",
|
||||
"@shareAlbumSuccessNotification": {
|
||||
"description": "Shared an album with another user successfully",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"example": "Alice"
|
||||
}
|
||||
}
|
||||
},
|
||||
"shareAlbumSuccessWithErrorNotification": "Album shared with {user}, but failed to share some files",
|
||||
"@shareAlbumSuccessWithErrorNotification": {
|
||||
"description": "Shared an album with another user successfully, but some files inside the album cannot be shared",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"example": "Alice"
|
||||
}
|
||||
}
|
||||
},
|
||||
"unshareAlbumSuccessNotification": "Album unshared with {user}",
|
||||
"@unshareAlbumSuccessNotification": {
|
||||
"description": "Unshared an album with another user successfully",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"example": "Alice"
|
||||
}
|
||||
}
|
||||
},
|
||||
"unshareAlbumSuccessWithErrorNotification": "Album unshared with {user}, but failed to unshare some files",
|
||||
"@unshareAlbumSuccessWithErrorNotification": {
|
||||
"description": "Unshared an album with another user successfully, but some files inside the album cannot be unshared",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"example": "Alice"
|
||||
}
|
||||
}
|
||||
},
|
||||
"fixSharesTooltip": "Fix shares",
|
||||
"@fixSharesTooltip": {
|
||||
"description": "Fix file shares in an album. Due to limitation of the server API, album and its files are shared separately, but they are both needed for shared album to work correctly. This button will attempt to synchronize them"
|
||||
|
@ -979,6 +1015,10 @@
|
|||
"@fixTooltip": {
|
||||
"description": "Fix an issue"
|
||||
},
|
||||
"fixButtonLabel": "FIX",
|
||||
"@fixButtonLabel":{
|
||||
"description": "Fix an issue"
|
||||
},
|
||||
"fixAllTooltip": "Fix all",
|
||||
"@fixAllTooltip": {
|
||||
"description": "Fix all listed issues"
|
||||
|
|
|
@ -25,8 +25,13 @@
|
|||
"addToCollectionTooltip",
|
||||
"addToCollectionProcessingNotification",
|
||||
"addToCollectionSuccessNotification",
|
||||
"shareAlbumSuccessNotification",
|
||||
"shareAlbumSuccessWithErrorNotification",
|
||||
"unshareAlbumSuccessNotification",
|
||||
"unshareAlbumSuccessWithErrorNotification",
|
||||
"fixSharesTooltip",
|
||||
"fixTooltip",
|
||||
"fixButtonLabel",
|
||||
"fixAllTooltip",
|
||||
"missingShareDescription",
|
||||
"extraShareDescription"
|
||||
|
@ -72,8 +77,13 @@
|
|||
"addToCollectionTooltip",
|
||||
"addToCollectionProcessingNotification",
|
||||
"addToCollectionSuccessNotification",
|
||||
"shareAlbumSuccessNotification",
|
||||
"shareAlbumSuccessWithErrorNotification",
|
||||
"unshareAlbumSuccessNotification",
|
||||
"unshareAlbumSuccessWithErrorNotification",
|
||||
"fixSharesTooltip",
|
||||
"fixTooltip",
|
||||
"fixButtonLabel",
|
||||
"fixAllTooltip",
|
||||
"missingShareDescription",
|
||||
"extraShareDescription"
|
||||
|
@ -174,8 +184,13 @@
|
|||
"addToCollectionTooltip",
|
||||
"addToCollectionProcessingNotification",
|
||||
"addToCollectionSuccessNotification",
|
||||
"shareAlbumSuccessNotification",
|
||||
"shareAlbumSuccessWithErrorNotification",
|
||||
"unshareAlbumSuccessNotification",
|
||||
"unshareAlbumSuccessWithErrorNotification",
|
||||
"fixSharesTooltip",
|
||||
"fixTooltip",
|
||||
"fixButtonLabel",
|
||||
"fixAllTooltip",
|
||||
"missingShareDescription",
|
||||
"extraShareDescription"
|
||||
|
@ -207,8 +222,13 @@
|
|||
"addToCollectionTooltip",
|
||||
"addToCollectionProcessingNotification",
|
||||
"addToCollectionSuccessNotification",
|
||||
"shareAlbumSuccessNotification",
|
||||
"shareAlbumSuccessWithErrorNotification",
|
||||
"unshareAlbumSuccessNotification",
|
||||
"unshareAlbumSuccessWithErrorNotification",
|
||||
"fixSharesTooltip",
|
||||
"fixTooltip",
|
||||
"fixButtonLabel",
|
||||
"fixAllTooltip",
|
||||
"missingShareDescription",
|
||||
"extraShareDescription"
|
||||
|
@ -289,8 +309,13 @@
|
|||
"addToCollectionTooltip",
|
||||
"addToCollectionProcessingNotification",
|
||||
"addToCollectionSuccessNotification",
|
||||
"shareAlbumSuccessNotification",
|
||||
"shareAlbumSuccessWithErrorNotification",
|
||||
"unshareAlbumSuccessNotification",
|
||||
"unshareAlbumSuccessWithErrorNotification",
|
||||
"fixSharesTooltip",
|
||||
"fixTooltip",
|
||||
"fixButtonLabel",
|
||||
"fixAllTooltip",
|
||||
"missingShareDescription",
|
||||
"extraShareDescription"
|
||||
|
@ -344,8 +369,13 @@
|
|||
"addToCollectionTooltip",
|
||||
"addToCollectionProcessingNotification",
|
||||
"addToCollectionSuccessNotification",
|
||||
"shareAlbumSuccessNotification",
|
||||
"shareAlbumSuccessWithErrorNotification",
|
||||
"unshareAlbumSuccessNotification",
|
||||
"unshareAlbumSuccessWithErrorNotification",
|
||||
"fixSharesTooltip",
|
||||
"fixTooltip",
|
||||
"fixButtonLabel",
|
||||
"fixAllTooltip",
|
||||
"missingShareDescription",
|
||||
"extraShareDescription"
|
||||
|
|
60
lib/use_case/list_shared_album.dart
Normal file
60
lib/use_case/list_shared_album.dart
Normal file
|
@ -0,0 +1,60 @@
|
|||
import 'package:nc_photos/account.dart';
|
||||
import 'package:nc_photos/entity/album.dart';
|
||||
import 'package:nc_photos/entity/file.dart';
|
||||
import 'package:nc_photos/entity/share.dart';
|
||||
import 'package:nc_photos/remote_storage_util.dart' as remote_storage_util;
|
||||
import 'package:nc_photos/use_case/ls.dart';
|
||||
|
||||
class ListSharedAlbumItem {
|
||||
const ListSharedAlbumItem(this.share, this.album);
|
||||
|
||||
final Share share;
|
||||
final Album album;
|
||||
}
|
||||
|
||||
class ListSharedAlbum {
|
||||
const ListSharedAlbum(this.shareRepo, this.fileRepo, this.albumRepo);
|
||||
|
||||
/// List albums that are currently shared by you
|
||||
///
|
||||
/// If [whereShareWith] is not null, only shares sharing with [whereShareWith]
|
||||
/// will be returned.
|
||||
Future<List<ListSharedAlbumItem>> call(
|
||||
Account account, {
|
||||
String? whereShareWith,
|
||||
}) async {
|
||||
final shares = await shareRepo.listDir(
|
||||
account, File(path: remote_storage_util.getRemoteAlbumsDir(account)));
|
||||
final shareGroups = <String, List<Share>>{};
|
||||
for (final s in shares) {
|
||||
shareGroups[s.path] ??= <Share>[];
|
||||
shareGroups[s.path]!.add(s);
|
||||
}
|
||||
final files = await Ls(fileRepo)(
|
||||
account,
|
||||
File(path: remote_storage_util.getRemoteAlbumsDir(account)),
|
||||
);
|
||||
|
||||
final products = <ListSharedAlbumItem>[];
|
||||
for (final sg in shareGroups.entries) {
|
||||
// find the file
|
||||
final albumFile =
|
||||
files.firstWhere((element) => element.strippedPath == sg.key);
|
||||
final album = await albumRepo.get(
|
||||
account,
|
||||
albumFile,
|
||||
);
|
||||
for (final s in sg.value) {
|
||||
if (whereShareWith != null && s.shareWith != whereShareWith) {
|
||||
continue;
|
||||
}
|
||||
products.add(ListSharedAlbumItem(s, album));
|
||||
}
|
||||
}
|
||||
return products;
|
||||
}
|
||||
|
||||
final ShareRepo shareRepo;
|
||||
final FileRepo fileRepo;
|
||||
final AlbumRepo albumRepo;
|
||||
}
|
44
lib/use_case/share_album_with_user.dart
Normal file
44
lib/use_case/share_album_with_user.dart
Normal file
|
@ -0,0 +1,44 @@
|
|||
import 'package:logging/logging.dart';
|
||||
import 'package:nc_photos/account.dart';
|
||||
import 'package:nc_photos/debug_util.dart';
|
||||
import 'package:nc_photos/entity/album.dart';
|
||||
import 'package:nc_photos/entity/album/item.dart';
|
||||
import 'package:nc_photos/entity/album/provider.dart';
|
||||
import 'package:nc_photos/entity/file.dart';
|
||||
import 'package:nc_photos/entity/share.dart';
|
||||
import 'package:nc_photos/use_case/create_share.dart';
|
||||
|
||||
class ShareAlbumWithUser {
|
||||
ShareAlbumWithUser(this.shareRepo);
|
||||
|
||||
Future<void> call(
|
||||
Account account,
|
||||
Album album,
|
||||
String shareWith, {
|
||||
void Function(File)? onShareFileFailed,
|
||||
}) async {
|
||||
assert(album.provider is AlbumStaticProvider);
|
||||
final files = AlbumStaticProvider.of(album)
|
||||
.items
|
||||
.whereType<AlbumFileItem>()
|
||||
.map((e) => e.file);
|
||||
await CreateUserShare(shareRepo)(account, album.albumFile!, shareWith);
|
||||
for (final f in files) {
|
||||
_log.info("[call] Sharing '${f.path}' with '$shareWith'");
|
||||
try {
|
||||
await CreateUserShare(shareRepo)(account, f, shareWith);
|
||||
} catch (e, stackTrace) {
|
||||
_log.severe(
|
||||
"[call] Failed sharing file '${logFilename(f.path)}' with '$shareWith'",
|
||||
e,
|
||||
stackTrace);
|
||||
onShareFileFailed?.call(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final ShareRepo shareRepo;
|
||||
|
||||
static final _log =
|
||||
Logger("use_case.share_album_with_user.ShareAlbumWithUser");
|
||||
}
|
84
lib/use_case/unshare_album_with_user.dart
Normal file
84
lib/use_case/unshare_album_with_user.dart
Normal file
|
@ -0,0 +1,84 @@
|
|||
import 'package:logging/logging.dart';
|
||||
import 'package:nc_photos/account.dart';
|
||||
import 'package:nc_photos/entity/album.dart';
|
||||
import 'package:nc_photos/entity/album/item.dart';
|
||||
import 'package:nc_photos/entity/album/provider.dart';
|
||||
import 'package:nc_photos/entity/file.dart';
|
||||
import 'package:nc_photos/entity/share.dart';
|
||||
import 'package:nc_photos/entity/share/data_source.dart';
|
||||
import 'package:nc_photos/use_case/list_share.dart';
|
||||
import 'package:nc_photos/use_case/list_shared_album.dart';
|
||||
import 'package:nc_photos/use_case/remove_share.dart';
|
||||
|
||||
class UnshareAlbumWithUser {
|
||||
UnshareAlbumWithUser(this.shareRepo, this.fileRepo, this.albumRepo);
|
||||
|
||||
Future<void> call(
|
||||
Account account,
|
||||
Album album,
|
||||
String shareWith, {
|
||||
void Function(File)? onUnshareFileFailed,
|
||||
}) async {
|
||||
assert(album.provider is AlbumStaticProvider);
|
||||
final shareRepo = ShareRepo(ShareRemoteDataSource());
|
||||
final sharedItems =
|
||||
await ListSharedAlbum(shareRepo, fileRepo, albumRepo)(account);
|
||||
final thisShare = sharedItems
|
||||
.firstWhere((element) =>
|
||||
element.share.path == album.albumFile!.strippedPath &&
|
||||
element.share.shareWith == shareWith)
|
||||
.share;
|
||||
final otherSharedAlbums = sharedItems
|
||||
.where((element) =>
|
||||
!identical(element.share, thisShare) &&
|
||||
element.album.provider is AlbumStaticProvider &&
|
||||
element.share.shareWith == shareWith)
|
||||
.map((e) => e.album)
|
||||
.toList();
|
||||
|
||||
final unsharingFiles = await _getExclusiveSharedFiles(
|
||||
account, album, otherSharedAlbums, shareWith);
|
||||
await RemoveShare(shareRepo)(account, thisShare);
|
||||
for (final f in unsharingFiles) {
|
||||
_log.info("[call] Unsharing '${f.path}'");
|
||||
try {
|
||||
final shares = await ListShare(shareRepo)(account, f);
|
||||
final share =
|
||||
shares.firstWhere((element) => element.shareWith == shareWith);
|
||||
await RemoveShare(shareRepo)(account, share);
|
||||
} catch (e, stackTrace) {
|
||||
_log.severe(
|
||||
"[call] Failed while RemoveShare: ${f.path}", e, stackTrace);
|
||||
onUnshareFileFailed?.call(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Return list of files shared with [shareWith] in [album] but not in
|
||||
/// [others]
|
||||
Future<List<File>> _getExclusiveSharedFiles(Account account, Album album,
|
||||
List<Album> others, String shareWith) async {
|
||||
var files = AlbumStaticProvider.of(album)
|
||||
.items
|
||||
.whereType<AlbumFileItem>()
|
||||
.map((e) => e.file)
|
||||
.toList();
|
||||
for (final a in others) {
|
||||
// filter out files in a
|
||||
files = files
|
||||
.where((f) => !AlbumStaticProvider.of(a)
|
||||
.items
|
||||
.whereType<AlbumFileItem>()
|
||||
.any((element) => element.file.path == f.path))
|
||||
.toList();
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
final ShareRepo shareRepo;
|
||||
final FileRepo fileRepo;
|
||||
final AlbumRepo albumRepo;
|
||||
|
||||
static final _log =
|
||||
Logger("use_case.unshare_album_with_user.UnshareAlbumWithUser");
|
||||
}
|
|
@ -325,7 +325,7 @@ class _AlbumBrowserState extends State<AlbumBrowser>
|
|||
context: context,
|
||||
builder: (_) => ShareAlbumDialog(
|
||||
account: widget.account,
|
||||
file: _album!.albumFile!,
|
||||
album: _album!,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -6,7 +6,9 @@ import 'package:nc_photos/account.dart';
|
|||
import 'package:nc_photos/app_localizations.dart';
|
||||
import 'package:nc_photos/bloc/list_share.dart';
|
||||
import 'package:nc_photos/bloc/list_sharee.dart';
|
||||
import 'package:nc_photos/entity/album.dart';
|
||||
import 'package:nc_photos/entity/file.dart';
|
||||
import 'package:nc_photos/entity/file/data_source.dart';
|
||||
import 'package:nc_photos/entity/share.dart';
|
||||
import 'package:nc_photos/entity/share/data_source.dart';
|
||||
import 'package:nc_photos/entity/sharee.dart';
|
||||
|
@ -14,20 +16,24 @@ import 'package:nc_photos/exception_util.dart' as exception_util;
|
|||
import 'package:nc_photos/iterable_extension.dart';
|
||||
import 'package:nc_photos/k.dart' as k;
|
||||
import 'package:nc_photos/snack_bar_manager.dart';
|
||||
import 'package:nc_photos/use_case/create_share.dart';
|
||||
import 'package:nc_photos/theme.dart';
|
||||
import 'package:nc_photos/use_case/share_album_with_user.dart';
|
||||
import 'package:nc_photos/use_case/unshare_album_with_user.dart';
|
||||
import 'package:nc_photos/widget/album_share_outlier_browser.dart';
|
||||
|
||||
class ShareAlbumDialog extends StatefulWidget {
|
||||
const ShareAlbumDialog({
|
||||
ShareAlbumDialog({
|
||||
Key? key,
|
||||
required this.account,
|
||||
required this.file,
|
||||
}) : super(key: key);
|
||||
required this.album,
|
||||
}) : assert(album.albumFile != null),
|
||||
super(key: key);
|
||||
|
||||
@override
|
||||
createState() => _ShareAlbumDialogState();
|
||||
|
||||
final Account account;
|
||||
final File file;
|
||||
final Album album;
|
||||
}
|
||||
|
||||
class _ShareAlbumDialogState extends State<ShareAlbumDialog> {
|
||||
|
@ -35,22 +41,32 @@ class _ShareAlbumDialogState extends State<ShareAlbumDialog> {
|
|||
initState() {
|
||||
super.initState();
|
||||
_shareeBloc.add(ListShareeBlocQuery(widget.account));
|
||||
_shareBloc.add(ListShareBlocQuery(widget.account, widget.file));
|
||||
_shareBloc.add(ListShareBlocQuery(widget.account, widget.album.albumFile!));
|
||||
}
|
||||
|
||||
@override
|
||||
build(BuildContext context) {
|
||||
return BlocListener<ListShareeBloc, ListShareeBlocState>(
|
||||
bloc: _shareeBloc,
|
||||
listener: (context, shareeState) =>
|
||||
_onListShareeBlocStateChanged(context, shareeState),
|
||||
child: BlocBuilder<ListShareeBloc, ListShareeBlocState>(
|
||||
bloc: _shareeBloc,
|
||||
builder: (_, shareeState) =>
|
||||
BlocBuilder<ListShareBloc, ListShareBlocState>(
|
||||
bloc: _shareBloc,
|
||||
builder: (context, shareState) =>
|
||||
_buildContent(context, shareeState, shareState),
|
||||
return AppTheme(
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Scaffold(
|
||||
backgroundColor: Colors.transparent,
|
||||
body: BlocListener<ListShareeBloc, ListShareeBlocState>(
|
||||
bloc: _shareeBloc,
|
||||
listener: (context, shareeState) =>
|
||||
_onListShareeBlocStateChanged(context, shareeState),
|
||||
child: BlocBuilder<ListShareeBloc, ListShareeBlocState>(
|
||||
bloc: _shareeBloc,
|
||||
builder: (_, shareeState) =>
|
||||
BlocBuilder<ListShareBloc, ListShareBlocState>(
|
||||
bloc: _shareBloc,
|
||||
builder: (context, shareState) =>
|
||||
_buildContent(context, shareeState, shareState),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
@ -89,13 +105,12 @@ class _ShareAlbumDialogState extends State<ShareAlbumDialog> {
|
|||
|
||||
Widget _buildItem(
|
||||
BuildContext context, ListShareBlocState shareState, Sharee sharee) {
|
||||
final Share? share;
|
||||
final bool isShared;
|
||||
if (_overrideSharee.containsKey(sharee.shareWith)) {
|
||||
share = _overrideSharee[sharee.shareWith];
|
||||
isShared = _overrideSharee[sharee.shareWith]!;
|
||||
} else {
|
||||
share = shareState.items
|
||||
.where((element) => element.shareWith == sharee.shareWith)
|
||||
.firstOrNull;
|
||||
isShared = shareState.items
|
||||
.any((element) => element.shareWith == sharee.shareWith);
|
||||
}
|
||||
|
||||
final isProcessing =
|
||||
|
@ -112,7 +127,7 @@ class _ShareAlbumDialogState extends State<ShareAlbumDialog> {
|
|||
);
|
||||
} else {
|
||||
trailing = Checkbox(
|
||||
value: share != null,
|
||||
value: isShared,
|
||||
onChanged: (value) {},
|
||||
);
|
||||
}
|
||||
|
@ -125,7 +140,7 @@ class _ShareAlbumDialogState extends State<ShareAlbumDialog> {
|
|||
child: trailing,
|
||||
),
|
||||
),
|
||||
onPressed: () => _onShareePressed(sharee, share),
|
||||
onPressed: () => _onShareePressed(sharee, isShared),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -139,49 +154,110 @@ class _ShareAlbumDialogState extends State<ShareAlbumDialog> {
|
|||
}
|
||||
}
|
||||
|
||||
void _onShareePressed(Sharee sharee, Share? share) async {
|
||||
final shareRepo = ShareRepo(ShareRemoteDataSource());
|
||||
void _onShareePressed(Sharee sharee, bool isShared) async {
|
||||
setState(() {
|
||||
_processingSharee.add(sharee.shareWith);
|
||||
});
|
||||
if (share == null) {
|
||||
if (!isShared) {
|
||||
// create new share
|
||||
try {
|
||||
final newShare = await CreateUserShare(shareRepo)(
|
||||
widget.account, widget.file, sharee.shareWith);
|
||||
_overrideSharee[sharee.shareWith] = newShare;
|
||||
} catch (e, stackTrace) {
|
||||
_log.shout("[_onShareePressed] Failed while create", e, stackTrace);
|
||||
SnackBarManager().showSnackBar(SnackBar(
|
||||
content: Text(exception_util.toUserString(e)),
|
||||
duration: k.snackBarDurationNormal,
|
||||
));
|
||||
}
|
||||
await _createShare(sharee);
|
||||
} else {
|
||||
// remove share
|
||||
try {
|
||||
await Future.delayed(const Duration(seconds: 3));
|
||||
await shareRepo.delete(widget.account, share);
|
||||
_overrideSharee[sharee.shareWith] = null;
|
||||
} catch (e, stackTrace) {
|
||||
_log.shout("[_onShareePressed] Failed while delete", e, stackTrace);
|
||||
SnackBarManager().showSnackBar(SnackBar(
|
||||
content: Text(exception_util.toUserString(e)),
|
||||
duration: k.snackBarDurationNormal,
|
||||
));
|
||||
}
|
||||
await _removeShare(sharee);
|
||||
}
|
||||
setState(() {
|
||||
_processingSharee.remove(sharee.shareWith);
|
||||
});
|
||||
}
|
||||
|
||||
void _onFixPressed() {
|
||||
Navigator.of(context).pushNamed(AlbumShareOutlierBrowser.routeName,
|
||||
arguments:
|
||||
AlbumShareOutlierBrowserArguments(widget.account, widget.album));
|
||||
}
|
||||
|
||||
Future<void> _createShare(Sharee sharee) async {
|
||||
final shareRepo = ShareRepo(ShareRemoteDataSource());
|
||||
var hasFailure = false;
|
||||
try {
|
||||
await ShareAlbumWithUser(shareRepo)(
|
||||
widget.account,
|
||||
widget.album,
|
||||
sharee.shareWith,
|
||||
onShareFileFailed: (_) {
|
||||
hasFailure = true;
|
||||
},
|
||||
);
|
||||
_overrideSharee[sharee.shareWith] = true;
|
||||
SnackBarManager().showSnackBar(SnackBar(
|
||||
content: Text(hasFailure
|
||||
? L10n.global()
|
||||
.shareAlbumSuccessWithErrorNotification(sharee.shareWith)
|
||||
: L10n.global().shareAlbumSuccessNotification(sharee.shareWith)),
|
||||
action: hasFailure
|
||||
? SnackBarAction(
|
||||
label: L10n.global().fixButtonLabel,
|
||||
textColor: Theme.of(context).colorScheme.secondaryVariant,
|
||||
onPressed: _onFixPressed,
|
||||
)
|
||||
: null,
|
||||
duration: k.snackBarDurationNormal,
|
||||
));
|
||||
} catch (e, stackTrace) {
|
||||
_log.shout(
|
||||
"[_createShare] Failed while ShareAlbumWithUser", e, stackTrace);
|
||||
SnackBarManager().showSnackBar(SnackBar(
|
||||
content: Text(exception_util.toUserString(e)),
|
||||
duration: k.snackBarDurationNormal,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _removeShare(Sharee sharee) async {
|
||||
final shareRepo = ShareRepo(ShareRemoteDataSource());
|
||||
final fileRepo = FileRepo(FileCachedDataSource());
|
||||
final albumRepo = AlbumRepo(AlbumCachedDataSource());
|
||||
var hasFailure = false;
|
||||
try {
|
||||
await UnshareAlbumWithUser(shareRepo, fileRepo, albumRepo)(
|
||||
widget.account,
|
||||
widget.album,
|
||||
sharee.shareWith,
|
||||
onUnshareFileFailed: (_) {
|
||||
hasFailure = true;
|
||||
},
|
||||
);
|
||||
_overrideSharee[sharee.shareWith] = false;
|
||||
SnackBarManager().showSnackBar(SnackBar(
|
||||
content: Text(hasFailure
|
||||
? L10n.global()
|
||||
.unshareAlbumSuccessWithErrorNotification(sharee.shareWith)
|
||||
: L10n.global().unshareAlbumSuccessNotification(sharee.shareWith)),
|
||||
action: hasFailure
|
||||
? SnackBarAction(
|
||||
label: L10n.global().fixButtonLabel,
|
||||
textColor: Theme.of(context).colorScheme.secondaryVariant,
|
||||
onPressed: _onFixPressed,
|
||||
)
|
||||
: null,
|
||||
duration: k.snackBarDurationNormal,
|
||||
));
|
||||
} catch (e, stackTrace) {
|
||||
_log.shout(
|
||||
"[_removeShare] Failed while UnshareAlbumWithUser", e, stackTrace);
|
||||
SnackBarManager().showSnackBar(SnackBar(
|
||||
content: Text(exception_util.toUserString(e)),
|
||||
duration: k.snackBarDurationNormal,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
final _shareeBloc = ListShareeBloc();
|
||||
final _shareBloc = ListShareBloc();
|
||||
final _processingSharee = <String>[];
|
||||
|
||||
/// Store the modified value of each sharee
|
||||
final _overrideSharee = <String, Share?>{};
|
||||
final _overrideSharee = <String, bool>{};
|
||||
|
||||
static final _log =
|
||||
Logger("widget.share_album_dialog._ShareAlbumDialogState");
|
||||
|
|
Loading…
Reference in a new issue