ente/lib/ui/sharing/share_collection_page.dart

401 lines
12 KiB
Dart
Raw Normal View History

import 'package:collection/collection.dart';
import 'package:fast_base58/fast_base58.dart';
2020-05-17 12:39:38 +00:00
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
2023-04-05 04:30:41 +00:00
import "package:photos/generated/l10n.dart";
import "package:photos/models/api/collection/user.dart";
2023-08-25 04:39:30 +00:00
import 'package:photos/models/collection/collection.dart';
2020-10-09 23:51:20 +00:00
import 'package:photos/services/collections_service.dart';
import 'package:photos/theme/ente_theme.dart';
import 'package:photos/ui/actions/collection/collection_sharing_actions.dart';
import 'package:photos/ui/components/captioned_text_widget.dart';
import 'package:photos/ui/components/divider_widget.dart';
2023-01-31 12:21:57 +00:00
import 'package:photos/ui/components/menu_item_widget/menu_item_widget.dart';
2022-12-17 07:25:15 +00:00
import 'package:photos/ui/components/menu_section_description_widget.dart';
import 'package:photos/ui/components/menu_section_title.dart';
import 'package:photos/ui/sharing/add_partipant_page.dart';
2022-11-22 11:33:34 +00:00
import 'package:photos/ui/sharing/album_participants_page.dart';
import "package:photos/ui/sharing/album_share_info_widget.dart";
import "package:photos/ui/sharing/manage_album_participant.dart";
2022-07-01 14:39:02 +00:00
import 'package:photos/ui/sharing/manage_links_widget.dart';
2022-11-22 11:33:34 +00:00
import 'package:photos/ui/sharing/user_avator_widget.dart';
2022-02-21 02:13:10 +00:00
import 'package:photos/utils/navigation_util.dart';
2020-10-09 23:51:20 +00:00
import 'package:photos/utils/share_util.dart';
2020-07-07 21:46:14 +00:00
import 'package:photos/utils/toast_util.dart';
2020-05-17 12:39:38 +00:00
2022-11-20 11:55:12 +00:00
class ShareCollectionPage extends StatefulWidget {
2020-10-13 06:23:45 +00:00
final Collection collection;
2022-12-27 12:23:25 +00:00
const ShareCollectionPage(this.collection, {Key? key}) : super(key: key);
2020-10-13 06:23:45 +00:00
@override
2022-11-20 11:55:12 +00:00
State<ShareCollectionPage> createState() => _ShareCollectionPageState();
2020-10-13 06:23:45 +00:00
}
2022-11-20 11:55:12 +00:00
class _ShareCollectionPageState extends State<ShareCollectionPage> {
2022-12-27 12:23:25 +00:00
late List<User?> _sharees;
2022-12-15 10:02:46 +00:00
final CollectionActions collectionActions =
CollectionActions(CollectionsService.instance);
2020-10-13 06:23:45 +00:00
2022-11-22 11:33:34 +00:00
Future<void> _navigateToManageUser() async {
if (_sharees.length == 1) {
await routeToPage(
context,
ManageIndividualParticipant(
collection: widget.collection,
user: _sharees.first!,
),
);
} else {
await routeToPage(
context,
AlbumParticipantsPage(widget.collection),
);
}
2022-11-22 11:33:34 +00:00
if (mounted) {
setState(() => {});
}
}
2020-10-13 06:23:45 +00:00
@override
Widget build(BuildContext context) {
_sharees = widget.collection.sharees ?? [];
2023-01-25 11:02:08 +00:00
final bool hasUrl = widget.collection.hasLink;
final children = <Widget>[];
2022-11-21 10:39:14 +00:00
children.add(
MenuSectionTitle(
2023-04-05 05:17:14 +00:00
title: S.of(context).shareWithPeopleSectionTitle(_sharees.length),
2022-11-21 10:39:14 +00:00
iconData: Icons.workspaces,
),
);
2022-11-22 06:39:48 +00:00
2022-11-22 11:33:34 +00:00
children.add(
EmailItemWidget(
widget.collection,
onTap: _navigateToManageUser,
),
);
2022-11-22 06:39:48 +00:00
children.add(
MenuItemWidget(
2023-05-02 07:03:42 +00:00
captionedTextWidget: CaptionedTextWidget(
title: S.of(context).addViewer,
makeTextBold: true,
2020-10-09 23:51:20 +00:00
),
leadingIcon: Icons.add,
menuItemColor: getEnteColorScheme(context).fillFaint,
2022-12-16 04:12:18 +00:00
isTopBorderRadiusRemoved: _sharees.isNotEmpty,
2023-01-30 17:45:26 +00:00
isBottomBorderRadiusRemoved: true,
onTap: () async {
2023-01-30 17:45:26 +00:00
routeToPage(
context,
AddParticipantPage(widget.collection, true),
).then(
(value) => {
2023-08-19 11:39:56 +00:00
if (mounted) {setState(() => {})},
2023-01-30 17:45:26 +00:00
},
);
},
),
);
children.add(
DividerWidget(
dividerType: DividerType.menu,
bgColor: getEnteColorScheme(context).fillFaint,
),
);
children.add(
MenuItemWidget(
2023-04-05 04:30:41 +00:00
captionedTextWidget: CaptionedTextWidget(
title: S.of(context).addCollaborator,
2023-01-30 17:45:26 +00:00
makeTextBold: true,
),
leadingIcon: Icons.add,
menuItemColor: getEnteColorScheme(context).fillFaint,
2023-02-01 14:19:16 +00:00
isTopBorderRadiusRemoved: true,
2023-01-30 17:45:26 +00:00
onTap: () async {
routeToPage(context, AddParticipantPage(widget.collection, false))
.then(
2022-11-22 11:33:34 +00:00
(value) => {
2023-08-19 11:39:56 +00:00
if (mounted) {setState(() => {})},
2022-11-22 11:33:34 +00:00
},
);
},
),
);
2022-12-17 07:25:15 +00:00
if (_sharees.isEmpty && !hasUrl) {
children.add(
2023-04-05 04:30:41 +00:00
MenuSectionDescriptionWidget(
content: S.of(context).sharedAlbumSectionDescription,
2022-12-17 07:25:15 +00:00
),
);
}
2020-10-13 05:22:20 +00:00
2022-11-22 08:10:58 +00:00
final bool hasExpired =
2022-12-30 03:29:48 +00:00
widget.collection.publicURLs?.firstOrNull?.isExpired ?? false;
2022-09-15 05:34:22 +00:00
children.addAll([
const SizedBox(
height: 24,
),
MenuSectionTitle(
2023-04-05 04:30:41 +00:00
title:
hasUrl ? S.of(context).publicLinkEnabled : S.of(context).shareALink,
iconData: Icons.public,
),
2022-09-15 05:34:22 +00:00
]);
if (hasUrl) {
2022-11-22 08:10:58 +00:00
if (hasExpired) {
children.add(
MenuItemWidget(
2022-11-22 08:10:58 +00:00
captionedTextWidget: CaptionedTextWidget(
2023-04-05 04:30:41 +00:00
title: S.of(context).linkHasExpired,
2022-11-22 08:10:58 +00:00
textColor: getEnteColorScheme(context).warning500,
),
2022-11-22 08:10:58 +00:00
leadingIcon: Icons.error_outline,
leadingIconColor: getEnteColorScheme(context).warning500,
menuItemColor: getEnteColorScheme(context).fillFaint,
isBottomBorderRadiusRemoved: true,
),
2022-11-22 08:10:58 +00:00
);
} else {
final String collectionKey = Base58Encode(
CollectionsService.instance.getCollectionKey(widget.collection.id),
);
final String url =
2022-12-27 12:23:25 +00:00
"${widget.collection.publicURLs!.first!.url}#$collectionKey";
2022-11-22 08:10:58 +00:00
children.addAll(
[
MenuItemWidget(
2023-04-05 04:30:41 +00:00
captionedTextWidget: CaptionedTextWidget(
title: S.of(context).copyLink,
2022-11-22 08:10:58 +00:00
makeTextBold: true,
),
leadingIcon: Icons.copy,
menuItemColor: getEnteColorScheme(context).fillFaint,
showOnlyLoadingState: true,
2022-11-22 08:10:58 +00:00
onTap: () async {
await Clipboard.setData(ClipboardData(text: url));
2023-05-02 07:03:42 +00:00
showShortToast(context, S.of(context).linkCopiedToClipboard);
2022-11-22 08:10:58 +00:00
},
isBottomBorderRadiusRemoved: true,
),
2022-11-22 08:10:58 +00:00
DividerWidget(
dividerType: DividerType.menu,
2022-12-16 08:28:54 +00:00
bgColor: getEnteColorScheme(context).fillFaint,
2022-11-22 08:10:58 +00:00
),
MenuItemWidget(
2023-04-05 04:30:41 +00:00
captionedTextWidget: CaptionedTextWidget(
title: S.of(context).sendLink,
2022-11-22 08:10:58 +00:00
makeTextBold: true,
),
leadingIcon: Icons.adaptive.share,
menuItemColor: getEnteColorScheme(context).fillFaint,
onTap: () async {
shareText(url);
},
isTopBorderRadiusRemoved: true,
2022-12-16 04:51:17 +00:00
isBottomBorderRadiusRemoved: true,
2022-11-22 08:10:58 +00:00
),
],
);
}
children.addAll(
[
DividerWidget(
dividerType: DividerType.menu,
2022-12-16 08:28:54 +00:00
bgColor: getEnteColorScheme(context).fillFaint,
),
MenuItemWidget(
2023-04-05 04:30:41 +00:00
captionedTextWidget: CaptionedTextWidget(
title: S.of(context).manageLink,
2022-11-21 10:39:14 +00:00
makeTextBold: true,
),
leadingIcon: Icons.link,
trailingIcon: Icons.navigate_next,
menuItemColor: getEnteColorScheme(context).fillFaint,
2022-11-21 10:39:14 +00:00
trailingIconIsMuted: true,
onTap: () async {
routeToPage(
context,
ManageSharedLinkWidget(collection: widget.collection),
).then(
(value) => {
2023-08-19 11:39:56 +00:00
if (mounted) {setState(() => {})},
},
);
},
isTopBorderRadiusRemoved: true,
),
],
);
} else {
2023-01-30 15:39:40 +00:00
children.addAll([
MenuItemWidget(
2023-04-05 04:30:41 +00:00
captionedTextWidget: CaptionedTextWidget(
title: S.of(context).createPublicLink,
2023-01-30 17:45:26 +00:00
makeTextBold: true,
),
leadingIcon: Icons.link,
menuItemColor: getEnteColorScheme(context).fillFaint,
showOnlyLoadingState: true,
onTap: () async {
final bool result =
await collectionActions.enableUrl(context, widget.collection);
if (result && mounted) {
setState(() => {});
}
},
2022-09-15 05:34:22 +00:00
),
_sharees.isEmpty
2023-04-05 04:30:41 +00:00
? MenuSectionDescriptionWidget(
content: S.of(context).shareWithNonenteUsers,
)
: const SizedBox.shrink(),
const SizedBox(
height: 24,
),
2023-04-05 04:30:41 +00:00
MenuSectionTitle(
title: S.of(context).collaborativeLink,
iconData: Icons.public,
2023-01-30 15:39:40 +00:00
),
MenuItemWidget(
2023-04-05 04:30:41 +00:00
captionedTextWidget: CaptionedTextWidget(
title: S.of(context).collectPhotos,
2023-01-30 17:45:26 +00:00
makeTextBold: true,
2023-01-30 15:39:40 +00:00
),
leadingIcon: Icons.link,
menuItemColor: getEnteColorScheme(context).fillFaint,
showOnlyLoadingState: true,
2023-01-30 15:39:40 +00:00
onTap: () async {
final bool result = await collectionActions.enableUrl(
context,
widget.collection,
enableCollect: true,
);
if (result && mounted) {
setState(() => {});
}
},
),
_sharees.isEmpty
2023-04-05 04:30:41 +00:00
? MenuSectionDescriptionWidget(
content: S.of(context).collabLinkSectionDescription,
)
: const SizedBox.shrink(),
2023-01-30 15:39:40 +00:00
]);
}
return Scaffold(
2022-12-17 07:25:15 +00:00
appBar: AppBar(
title: Text(
widget.collection.displayName,
2023-06-13 06:41:31 +00:00
style:
Theme.of(context).textTheme.headlineSmall?.copyWith(fontSize: 16),
2022-12-17 07:25:15 +00:00
),
elevation: 0,
centerTitle: false,
),
body: SingleChildScrollView(
2020-10-13 05:22:20 +00:00
child: ListBody(
children: <Widget>[
Padding(
padding:
const EdgeInsets.symmetric(vertical: 4.0, horizontal: 16),
2022-06-11 08:23:52 +00:00
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
2022-06-11 08:23:52 +00:00
children: children,
),
),
2020-10-13 05:22:20 +00:00
],
),
),
);
2020-10-09 23:51:20 +00:00
}
2020-08-07 10:21:56 +00:00
}
class EmailItemWidget extends StatelessWidget {
2021-03-21 11:21:45 +00:00
final Collection collection;
2022-12-27 12:23:25 +00:00
final Function? onTap;
2020-10-31 13:17:17 +00:00
2020-08-07 10:21:56 +00:00
const EmailItemWidget(
2022-11-22 11:33:34 +00:00
this.collection, {
this.onTap,
2022-12-27 12:23:25 +00:00
Key? key,
2020-08-07 10:21:56 +00:00
}) : super(key: key);
@override
Widget build(BuildContext context) {
2022-11-22 11:33:34 +00:00
if (collection.getSharees().isEmpty) {
return const SizedBox.shrink();
} else if (collection.getSharees().length == 1) {
return Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
MenuItemWidget(
captionedTextWidget: CaptionedTextWidget(
title: collection.getSharees().firstOrNull?.email ?? '',
),
2022-12-16 13:09:14 +00:00
leadingIconWidget: UserAvatarWidget(
collection.getSharees().first,
thumbnailView: false,
2022-12-16 13:09:14 +00:00
),
2022-11-22 11:33:34 +00:00
leadingIconSize: 24,
menuItemColor: getEnteColorScheme(context).fillFaint,
trailingIconIsMuted: true,
trailingIcon: Icons.chevron_right,
2022-11-21 10:39:14 +00:00
onTap: () async {
2022-11-22 11:33:34 +00:00
if (onTap != null) {
2022-12-27 12:23:25 +00:00
onTap!();
2022-11-22 11:33:34 +00:00
}
2022-11-21 10:39:14 +00:00
},
2022-11-22 11:33:34 +00:00
isBottomBorderRadiusRemoved: true,
),
DividerWidget(
2022-12-16 08:28:54 +00:00
dividerType: DividerType.menu,
bgColor: getEnteColorScheme(context).fillFaint,
2022-11-22 11:33:34 +00:00
),
],
);
} else {
return Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
MenuItemWidget(
captionedTextWidget: Flexible(
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 0),
child: SizedBox(
height: 24,
child: AlbumSharesIcons(
sharees: collection.getSharees(),
padding: const EdgeInsets.all(0),
limitCountTo: 10,
type: AvatarType.mini,
removeBorder: false,
),
),
),
2022-11-21 10:39:14 +00:00
),
alignCaptionedTextToLeft: true,
// leadingIcon: Icons.people_outline,
2022-11-22 11:33:34 +00:00
menuItemColor: getEnteColorScheme(context).fillFaint,
trailingIconIsMuted: true,
trailingIcon: Icons.chevron_right,
onTap: () async {
if (onTap != null) {
2022-12-27 12:23:25 +00:00
onTap!();
2022-11-22 11:33:34 +00:00
}
},
isBottomBorderRadiusRemoved: true,
),
2022-11-22 11:33:34 +00:00
DividerWidget(
dividerType: DividerType.menu,
2022-12-16 08:28:54 +00:00
bgColor: getEnteColorScheme(context).fillFaint,
2022-11-22 11:33:34 +00:00
),
],
);
}
2020-05-17 12:39:38 +00:00
}
}