manage_album_participant.dart 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. import 'package:flutter/material.dart';
  2. import 'package:photos/models/collection.dart';
  3. import 'package:photos/services/collections_service.dart';
  4. import 'package:photos/theme/colors.dart';
  5. import 'package:photos/theme/ente_theme.dart';
  6. import 'package:photos/ui/actions/collection/collection_sharing_actions.dart';
  7. import 'package:photos/ui/components/button_widget.dart';
  8. import 'package:photos/ui/components/captioned_text_widget.dart';
  9. import 'package:photos/ui/components/divider_widget.dart';
  10. import 'package:photos/ui/components/menu_item_widget/menu_item_widget.dart';
  11. import 'package:photos/ui/components/menu_section_description_widget.dart';
  12. import 'package:photos/ui/components/menu_section_title.dart';
  13. import 'package:photos/ui/components/title_bar_title_widget.dart';
  14. import 'package:photos/utils/dialog_util.dart';
  15. class ManageIndividualParticipant extends StatefulWidget {
  16. final Collection collection;
  17. final User user;
  18. const ManageIndividualParticipant({
  19. super.key,
  20. required this.collection,
  21. required this.user,
  22. });
  23. @override
  24. State<StatefulWidget> createState() => _ManageIndividualParticipantState();
  25. }
  26. class _ManageIndividualParticipantState
  27. extends State<ManageIndividualParticipant> {
  28. final CollectionActions collectionActions =
  29. CollectionActions(CollectionsService.instance);
  30. @override
  31. Widget build(BuildContext context) {
  32. final colorScheme = getEnteColorScheme(context);
  33. final textTheme = getEnteTextTheme(context);
  34. bool isConvertToViewSuccess = false;
  35. return Scaffold(
  36. appBar: AppBar(),
  37. body: Padding(
  38. padding: const EdgeInsets.symmetric(horizontal: 16.0),
  39. child: Column(
  40. mainAxisAlignment: MainAxisAlignment.start,
  41. crossAxisAlignment: CrossAxisAlignment.start,
  42. children: [
  43. SafeArea(
  44. child: Column(
  45. crossAxisAlignment: CrossAxisAlignment.start,
  46. children: [
  47. const SizedBox(
  48. height: 12,
  49. ),
  50. const TitleBarTitleWidget(
  51. title: "Manage",
  52. ),
  53. Text(
  54. widget.user.email.toString().trim(),
  55. textAlign: TextAlign.left,
  56. style:
  57. textTheme.small.copyWith(color: colorScheme.textMuted),
  58. ),
  59. ],
  60. ),
  61. ),
  62. const SizedBox(height: 12),
  63. const MenuSectionTitle(title: "Added as"),
  64. MenuItemWidget(
  65. captionedTextWidget: const CaptionedTextWidget(
  66. title: "Collaborator",
  67. ),
  68. leadingIcon: Icons.edit_outlined,
  69. menuItemColor: getEnteColorScheme(context).fillFaint,
  70. trailingIcon: widget.user.isCollaborator ? Icons.check : null,
  71. onTap: widget.user.isCollaborator
  72. ? null
  73. : () async {
  74. final result =
  75. await collectionActions.addEmailToCollection(
  76. context,
  77. widget.collection,
  78. widget.user.email,
  79. CollectionParticipantRole.collaborator,
  80. );
  81. if (result && mounted) {
  82. widget.user.role = CollectionParticipantRole
  83. .collaborator
  84. .toStringVal();
  85. setState(() => {});
  86. }
  87. },
  88. isBottomBorderRadiusRemoved: true,
  89. ),
  90. DividerWidget(
  91. dividerType: DividerType.menu,
  92. bgColor: getEnteColorScheme(context).fillFaint,
  93. ),
  94. MenuItemWidget(
  95. captionedTextWidget: const CaptionedTextWidget(
  96. title: "Viewer",
  97. ),
  98. leadingIcon: Icons.photo_outlined,
  99. leadingIconColor: getEnteColorScheme(context).strokeBase,
  100. menuItemColor: getEnteColorScheme(context).fillFaint,
  101. trailingIcon: widget.user.isViewer ? Icons.check : null,
  102. showOnlyLoadingState: true,
  103. onTap: widget.user.isViewer
  104. ? null
  105. : () async {
  106. final actionResult = await showChoiceActionSheet(
  107. context,
  108. title: "Change permissions?",
  109. firstButtonLabel: "Yes, convert to viewer",
  110. body:
  111. '${widget.user.email} will not be able to add more photos to this album\n\nThey will still be able to remove existing photos added by them',
  112. isCritical: true,
  113. );
  114. if (actionResult?.action != null) {
  115. if (actionResult!.action == ButtonAction.first) {
  116. try {
  117. isConvertToViewSuccess =
  118. await collectionActions.addEmailToCollection(
  119. context,
  120. widget.collection,
  121. widget.user.email,
  122. CollectionParticipantRole.viewer,
  123. );
  124. } catch (e) {
  125. showGenericErrorDialog(context: context);
  126. }
  127. if (isConvertToViewSuccess && mounted) {
  128. // reset value
  129. isConvertToViewSuccess = false;
  130. widget.user.role =
  131. CollectionParticipantRole.viewer.toStringVal();
  132. setState(() => {});
  133. }
  134. }
  135. }
  136. },
  137. isTopBorderRadiusRemoved: true,
  138. ),
  139. const MenuSectionDescriptionWidget(
  140. content:
  141. "Collaborators can add photos and videos to the shared album.",
  142. ),
  143. const SizedBox(height: 24),
  144. const MenuSectionTitle(title: "Remove participant"),
  145. MenuItemWidget(
  146. captionedTextWidget: const CaptionedTextWidget(
  147. title: "Remove",
  148. textColor: warning500,
  149. makeTextBold: true,
  150. ),
  151. leadingIcon: Icons.not_interested_outlined,
  152. leadingIconColor: warning500,
  153. menuItemColor: getEnteColorScheme(context).fillFaint,
  154. surfaceExecutionStates: false,
  155. onTap: () async {
  156. final result = await collectionActions.removeParticipant(
  157. context,
  158. widget.collection,
  159. widget.user,
  160. );
  161. if ((result) && mounted) {
  162. Navigator.of(context).pop(true);
  163. }
  164. },
  165. )
  166. ],
  167. ),
  168. ),
  169. );
  170. }
  171. }