123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379 |
- import 'package:collection/collection.dart';
- import 'package:fast_base58/fast_base58.dart';
- import 'package:flutter/material.dart';
- import 'package:flutter/services.dart';
- import 'package:photos/models/collection.dart';
- 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';
- import 'package:photos/ui/components/menu_item_widget/menu_item_widget.dart';
- 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';
- import 'package:photos/ui/sharing/album_participants_page.dart';
- import 'package:photos/ui/sharing/manage_links_widget.dart';
- import 'package:photos/ui/sharing/user_avator_widget.dart';
- import 'package:photos/utils/navigation_util.dart';
- import 'package:photos/utils/share_util.dart';
- import 'package:photos/utils/toast_util.dart';
- class ShareCollectionPage extends StatefulWidget {
- final Collection collection;
- const ShareCollectionPage(this.collection, {Key? key}) : super(key: key);
- @override
- State<ShareCollectionPage> createState() => _ShareCollectionPageState();
- }
- class _ShareCollectionPageState extends State<ShareCollectionPage> {
- late List<User?> _sharees;
- final CollectionActions collectionActions =
- CollectionActions(CollectionsService.instance);
- Future<void> _navigateToManageUser() async {
- await routeToPage(
- context,
- AlbumParticipantsPage(widget.collection),
- );
- if (mounted) {
- setState(() => {});
- }
- }
- @override
- Widget build(BuildContext context) {
- _sharees = widget.collection.sharees ?? [];
- final bool hasUrl = widget.collection.hasLink;
- final children = <Widget>[];
- children.add(
- MenuSectionTitle(
- title: _sharees.isEmpty
- ? "Share with specific people"
- : "Shared with ${_sharees.length} ${_sharees.length == 1 ? 'person' : 'people'}",
- iconData: Icons.workspaces,
- ),
- );
- children.add(
- EmailItemWidget(
- widget.collection,
- onTap: _navigateToManageUser,
- ),
- );
- children.add(
- MenuItemWidget(
- captionedTextWidget: const CaptionedTextWidget(
- title: "Add viewer",
- makeTextBold: true,
- ),
- leadingIcon: Icons.add,
- menuItemColor: getEnteColorScheme(context).fillFaint,
- isTopBorderRadiusRemoved: _sharees.isNotEmpty,
- isBottomBorderRadiusRemoved: true,
- onTap: () async {
- routeToPage(
- context,
- AddParticipantPage(widget.collection, true),
- ).then(
- (value) => {
- if (mounted) {setState(() => {})}
- },
- );
- },
- ),
- );
- children.add(
- DividerWidget(
- dividerType: DividerType.menu,
- bgColor: getEnteColorScheme(context).fillFaint,
- ),
- );
- children.add(
- MenuItemWidget(
- captionedTextWidget: const CaptionedTextWidget(
- title: "Add collaborator",
- makeTextBold: true,
- ),
- leadingIcon: Icons.add,
- menuItemColor: getEnteColorScheme(context).fillFaint,
- isTopBorderRadiusRemoved: true,
- onTap: () async {
- routeToPage(context, AddParticipantPage(widget.collection, false))
- .then(
- (value) => {
- if (mounted) {setState(() => {})}
- },
- );
- },
- ),
- );
- if (_sharees.isEmpty && !hasUrl) {
- children.add(
- const MenuSectionDescriptionWidget(
- content:
- "Create shared and collaborative albums with other ente users, "
- "including users on free plans.",
- ),
- );
- }
- final bool hasExpired =
- widget.collection.publicURLs?.firstOrNull?.isExpired ?? false;
- children.addAll([
- const SizedBox(
- height: 24,
- ),
- MenuSectionTitle(
- title: hasUrl ? "Public link enabled" : "Share a link",
- iconData: Icons.public,
- ),
- ]);
- if (hasUrl) {
- if (hasExpired) {
- children.add(
- MenuItemWidget(
- captionedTextWidget: CaptionedTextWidget(
- title: "Link has expired",
- textColor: getEnteColorScheme(context).warning500,
- ),
- leadingIcon: Icons.error_outline,
- leadingIconColor: getEnteColorScheme(context).warning500,
- menuItemColor: getEnteColorScheme(context).fillFaint,
- onTap: () async {},
- isBottomBorderRadiusRemoved: true,
- ),
- );
- } else {
- final String collectionKey = Base58Encode(
- CollectionsService.instance.getCollectionKey(widget.collection.id),
- );
- final String url =
- "${widget.collection.publicURLs!.first!.url}#$collectionKey";
- children.addAll(
- [
- MenuItemWidget(
- captionedTextWidget: const CaptionedTextWidget(
- title: "Copy link",
- makeTextBold: true,
- ),
- leadingIcon: Icons.copy,
- menuItemColor: getEnteColorScheme(context).fillFaint,
- showOnlyLoadingState: true,
- onTap: () async {
- await Clipboard.setData(ClipboardData(text: url));
- showShortToast(context, "Link copied to clipboard");
- },
- isBottomBorderRadiusRemoved: true,
- ),
- DividerWidget(
- dividerType: DividerType.menu,
- bgColor: getEnteColorScheme(context).fillFaint,
- ),
- MenuItemWidget(
- captionedTextWidget: const CaptionedTextWidget(
- title: "Send link",
- makeTextBold: true,
- ),
- leadingIcon: Icons.adaptive.share,
- menuItemColor: getEnteColorScheme(context).fillFaint,
- onTap: () async {
- shareText(url);
- },
- isTopBorderRadiusRemoved: true,
- isBottomBorderRadiusRemoved: true,
- ),
- ],
- );
- }
- children.addAll(
- [
- DividerWidget(
- dividerType: DividerType.menu,
- bgColor: getEnteColorScheme(context).fillFaint,
- ),
- MenuItemWidget(
- captionedTextWidget: const CaptionedTextWidget(
- title: "Manage link",
- makeTextBold: true,
- ),
- leadingIcon: Icons.link,
- trailingIcon: Icons.navigate_next,
- menuItemColor: getEnteColorScheme(context).fillFaint,
- trailingIconIsMuted: true,
- onTap: () async {
- routeToPage(
- context,
- ManageSharedLinkWidget(collection: widget.collection),
- ).then(
- (value) => {
- if (mounted) {setState(() => {})}
- },
- );
- },
- isTopBorderRadiusRemoved: true,
- ),
- ],
- );
- } else {
- children.addAll([
- MenuItemWidget(
- captionedTextWidget: const CaptionedTextWidget(
- title: "Create public link",
- makeTextBold: true,
- ),
- leadingIcon: Icons.link,
- menuItemColor: getEnteColorScheme(context).fillFaint,
- isBottomBorderRadiusRemoved: true,
- showOnlyLoadingState: true,
- onTap: () async {
- final bool result =
- await collectionActions.enableUrl(context, widget.collection);
- if (result && mounted) {
- setState(() => {});
- }
- },
- ),
- _sharees.isEmpty
- ? const MenuSectionDescriptionWidget(
- content: "Share with non-ente users",
- )
- : const SizedBox.shrink(),
- const SizedBox(
- height: 24,
- ),
- const MenuSectionTitle(
- title: "Collaborative link",
- iconData: Icons.public,
- ),
- MenuItemWidget(
- captionedTextWidget: const CaptionedTextWidget(
- title: "Collect photos",
- makeTextBold: true,
- ),
- leadingIcon: Icons.link,
- menuItemColor: getEnteColorScheme(context).fillFaint,
- showOnlyLoadingState: true,
- onTap: () async {
- final bool result = await collectionActions.enableUrl(
- context,
- widget.collection,
- enableCollect: true,
- );
- if (result && mounted) {
- setState(() => {});
- }
- },
- ),
- _sharees.isEmpty
- ? const MenuSectionDescriptionWidget(
- content:
- "Create a link to allow people to add and view photos in "
- "your shared album without needing an ente app or account. Great for collecting event photos.",
- )
- : const SizedBox.shrink(),
- ]);
- }
- return Scaffold(
- appBar: AppBar(
- title: Text(
- widget.collection.name ?? "Unnamed",
- style: Theme.of(context).textTheme.headline5?.copyWith(fontSize: 16),
- ),
- elevation: 0,
- centerTitle: false,
- ),
- body: SingleChildScrollView(
- child: ListBody(
- children: <Widget>[
- Padding(
- padding:
- const EdgeInsets.symmetric(vertical: 4.0, horizontal: 16),
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: children,
- ),
- ),
- ],
- ),
- ),
- );
- }
- }
- class EmailItemWidget extends StatelessWidget {
- final Collection collection;
- final Function? onTap;
- const EmailItemWidget(
- this.collection, {
- this.onTap,
- Key? key,
- }) : super(key: key);
- @override
- Widget build(BuildContext context) {
- 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 ?? '',
- ),
- leadingIconWidget: UserAvatarWidget(
- collection.getSharees().first,
- thumbnailView: true,
- ),
- leadingIconSize: 24,
- menuItemColor: getEnteColorScheme(context).fillFaint,
- trailingIconIsMuted: true,
- trailingIcon: Icons.chevron_right,
- onTap: () async {
- if (onTap != null) {
- onTap!();
- }
- },
- isBottomBorderRadiusRemoved: true,
- ),
- DividerWidget(
- dividerType: DividerType.menu,
- bgColor: getEnteColorScheme(context).fillFaint,
- ),
- ],
- );
- } else {
- return Column(
- mainAxisAlignment: MainAxisAlignment.start,
- children: [
- MenuItemWidget(
- captionedTextWidget: const CaptionedTextWidget(
- title: 'Manage',
- ),
- leadingIcon: Icons.people_outline,
- menuItemColor: getEnteColorScheme(context).fillFaint,
- trailingIconIsMuted: true,
- trailingIcon: Icons.chevron_right,
- onTap: () async {
- if (onTap != null) {
- onTap!();
- }
- },
- isBottomBorderRadiusRemoved: true,
- ),
- DividerWidget(
- dividerType: DividerType.menu,
- bgColor: getEnteColorScheme(context).fillFaint,
- ),
- ],
- );
- }
- }
- }
|