Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions mobile/apps/locker/lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,7 @@
"sharedByYou": "Shared by you",
"sharedWithYou": "Shared with you",
"manageLink": "Manage link",
"linkLabel": "Link",
"linkExpiry": "Link expiry",
"linkNeverExpires": "Never",
"linkExpired": "Expired",
Expand Down Expand Up @@ -915,6 +916,7 @@
"sorry": "Sorry",
"subscribe": "Subscribe",
"sharedWith": "Shared with",
"shareCollection": "Share collection",
"shareLater": "Share later",
"enterNameOrEmailToShareWith": "Enter name or email to share with",
"chooseFromAnExistingContact": "Choose from an existing contact",
Expand Down
12 changes: 12 additions & 0 deletions mobile/apps/locker/lib/l10n/app_localizations.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1590,6 +1590,12 @@ abstract class AppLocalizations {
/// **'Manage link'**
String get manageLink;

/// No description provided for @linkLabel.
///
/// In en, this message translates to:
/// **'Link'**
String get linkLabel;

/// No description provided for @linkExpiry.
///
/// In en, this message translates to:
Expand Down Expand Up @@ -2754,6 +2760,12 @@ abstract class AppLocalizations {
/// **'Shared with'**
String get sharedWith;

/// No description provided for @shareCollection.
///
/// In en, this message translates to:
/// **'Share collection'**
String get shareCollection;

/// No description provided for @shareLater.
///
/// In en, this message translates to:
Expand Down
6 changes: 6 additions & 0 deletions mobile/apps/locker/lib/l10n/app_localizations_en.dart
Original file line number Diff line number Diff line change
Expand Up @@ -810,6 +810,9 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get manageLink => 'Manage link';

@override
String get linkLabel => 'Link';

@override
String get linkExpiry => 'Link expiry';

Expand Down Expand Up @@ -1574,6 +1577,9 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get sharedWith => 'Shared with';

@override
String get shareCollection => 'Share collection';

@override
String get shareLater => 'Share later';

Expand Down
23 changes: 23 additions & 0 deletions mobile/apps/locker/lib/ui/components/input_sheet.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class InputSheet extends StatefulWidget {
final String? initialValue;
final TextCapitalization textCapitalization;
final int? maxLength;
final bool isPasswordInput;

const InputSheet({
super.key,
Expand All @@ -22,6 +23,7 @@ class InputSheet extends StatefulWidget {
this.initialValue,
this.textCapitalization = TextCapitalization.words,
this.maxLength = 200,
this.isPasswordInput = false,
});

@override
Expand All @@ -32,6 +34,7 @@ class _InputSheetState extends State<InputSheet> {
late final TextEditingController _textController;
bool _isSubmitting = false;
bool _isInputValid = false;
bool _isPasswordVisible = false;

@override
void initState() {
Expand Down Expand Up @@ -99,6 +102,9 @@ class _InputSheetState extends State<InputSheet> {
autofocus: true,
textCapitalization: widget.textCapitalization,
maxLength: widget.maxLength,
obscureText: widget.isPasswordInput && !_isPasswordVisible,
enableSuggestions: !widget.isPasswordInput,
autocorrect: !widget.isPasswordInput,
decoration: InputDecoration(
hintText: widget.hintText,
hintStyle: textTheme.body.copyWith(
Expand All @@ -120,6 +126,21 @@ class _InputSheetState extends State<InputSheet> {
color: colorScheme.strokeFaint,
),
),
suffixIcon: widget.isPasswordInput
? IconButton(
onPressed: () {
setState(() {
_isPasswordVisible = !_isPasswordVisible;
});
},
icon: Icon(
_isPasswordVisible
? Icons.visibility
: Icons.visibility_off,
color: colorScheme.textMuted,
),
)
: null,
counterText: "",
),
style: textTheme.body.copyWith(
Expand Down Expand Up @@ -149,6 +170,7 @@ Future<dynamic> showInputSheet(
String? initialValue,
TextCapitalization textCapitalization = TextCapitalization.words,
int? maxLength = 200,
bool isPasswordInput = false,
}) async {
return showBaseBottomSheet<dynamic>(
context,
Expand All @@ -163,6 +185,7 @@ Future<dynamic> showInputSheet(
initialValue: initialValue,
textCapitalization: textCapitalization,
maxLength: maxLength,
isPasswordInput: isPasswordInput,
),
);
}
178 changes: 15 additions & 163 deletions mobile/apps/locker/lib/ui/pages/collection_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,15 @@ import 'package:locker/services/collections/models/collection.dart';
import "package:locker/services/collections/models/collection_view_type.dart";
import "package:locker/services/configuration.dart";
import 'package:locker/services/files/sync/models/file.dart';
import "package:locker/ui/components/collection_popup_menu_widget.dart";
import "package:locker/ui/components/empty_state_widget.dart";
import 'package:locker/ui/components/item_list_view.dart';
import "package:locker/ui/components/popup_menu_item_widget.dart";
import 'package:locker/ui/components/search_result_view.dart';
import 'package:locker/ui/mixins/search_mixin.dart';
import 'package:locker/ui/pages/home_page.dart';
import 'package:locker/ui/pages/uploader_page.dart';
import "package:locker/ui/sharing/share_collection_bottom_sheet.dart";
import "package:locker/ui/viewer/actions/file_selection_overlay_bar.dart";
import 'package:locker/utils/collection_actions.dart';
import "package:logging/logging.dart";

class CollectionPage extends UploaderPage {
Expand All @@ -48,9 +47,6 @@ class _CollectionPageState extends UploaderPageState<CollectionPage>
final _logger = Logger("CollectionPage");
late StreamSubscription<CollectionsUpdatedEvent>
_collectionUpdateSubscription;
bool _isCollectionDeleted = false;
bool _isDeletingCollection = false;
bool _ignoreCollectionUpdates = false;

late Collection _collection;
List<EnteFile> _files = [];
Expand Down Expand Up @@ -121,9 +117,6 @@ class _CollectionPageState extends UploaderPageState<CollectionPage>
_initializeData(widget.collection);
_collectionUpdateSubscription =
Bus.instance.on<CollectionsUpdatedEvent>().listen((event) async {
if (_ignoreCollectionUpdates || _isCollectionDeleted) {
return;
}
_logger.info(
"CollectionsUpdatedEvent received on CollectionPage (${widget.collection.id}): ${event.source}",
);
Expand All @@ -142,7 +135,7 @@ class _CollectionPageState extends UploaderPageState<CollectionPage>
_logger.warning(
'Collection ${widget.collection.id} no longer exists, navigating back',
);
if (!_isCollectionDeleted && mounted) {
if (mounted) {
Navigator.of(context).pop();
}
}
Expand All @@ -165,43 +158,6 @@ class _CollectionPageState extends UploaderPageState<CollectionPage>
setState(() {});
}

Future<void> _deleteCollection() async {
if (_isDeletingCollection) {
return;
}
_isDeletingCollection = true;
_ignoreCollectionUpdates = true;
var didDelete = false;
try {
await CollectionActions.deleteCollection(
context,
_collection,
onSuccess: () {
didDelete = true;
_isCollectionDeleted = true;
if (mounted) {
Navigator.of(context).pop();
}
},
);
} finally {
if (!didDelete) {
_ignoreCollectionUpdates = false;
}
_isDeletingCollection = false;
}
}

Future<void> _editCollection() async {
await CollectionActions.editCollection(
context,
_collection,
onSuccess: () {
setState(() {});
},
);
}

Future<void> _shareCollection() async {
try {
if ((collectionViewType != CollectionViewType.ownedCollection &&
Expand All @@ -217,23 +173,15 @@ class _CollectionPageState extends UploaderPageState<CollectionPage>
}

await showShareCollectionSheet(context, collection: _collection);
// Refresh state after share sheet closes
if (mounted) {
setState(() {});
}
} catch (e, s) {
_logger.severe(e, s);
await showGenericErrorDialog(context: context, error: e);
await showGenericErrorBottomSheet(context: context, error: e);
}
}

Future<void> _leaveCollection() async {
await CollectionActions.leaveCollection(
context,
_collection,
);
}

@override
Widget build(BuildContext context) {
final colorScheme = getEnteColorScheme(context);
Expand Down Expand Up @@ -308,19 +256,18 @@ class _CollectionPageState extends UploaderPageState<CollectionPage>
if (isFavorite) {
return SizedBox.fromSize();
}
return PopupMenuButton<String>(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
side: BorderSide(color: colorScheme.strokeFaint),
),
color: colorScheme.backdropBase,
surfaceTintColor: Colors.transparent,
padding: EdgeInsets.zero,
menuPadding: EdgeInsets.zero,
elevation: 15,
shadowColor: Colors.black.withValues(alpha: 0.08),
constraints: const BoxConstraints(minWidth: 120),
offset: const Offset(-36, 36),
final canManageCollection = collectionViewType ==
CollectionViewType.ownedCollection ||
collectionViewType == CollectionViewType.hiddenOwnedCollection ||
collectionViewType == CollectionViewType.sharedCollectionViewer ||
collectionViewType == CollectionViewType.sharedCollectionCollaborator ||
collectionViewType == CollectionViewType.quickLink;
if (!canManageCollection) {
return SizedBox.fromSize();
}

return CollectionPopupMenuWidget(
collection: _collection,
child: Container(
height: 44,
width: 44,
Expand All @@ -334,101 +281,6 @@ class _CollectionPageState extends UploaderPageState<CollectionPage>
color: colorScheme.textBase,
),
),
onSelected: (value) {
switch (value) {
case 'edit':
_editCollection();
break;
case 'delete':
_deleteCollection();
break;
case 'leave_collection':
_leaveCollection();
break;
}
},
itemBuilder: (BuildContext context) {
final items = <PopupMenuItem<String>>[];
var itemIndex = 0;
var totalItems = 0;

if (collectionViewType == CollectionViewType.ownedCollection ||
collectionViewType == CollectionViewType.hiddenOwnedCollection ||
collectionViewType == CollectionViewType.quickLink) {
totalItems = 2;
} else if (collectionViewType ==
CollectionViewType.sharedCollectionViewer ||
collectionViewType ==
CollectionViewType.sharedCollectionCollaborator) {
totalItems = 1;
}

if (collectionViewType == CollectionViewType.ownedCollection ||
collectionViewType == CollectionViewType.hiddenOwnedCollection ||
collectionViewType == CollectionViewType.quickLink) {
items.add(
PopupMenuItem<String>(
value: 'edit',
height: 0,
padding: EdgeInsets.zero,
child: PopupMenuItemWidget(
icon: HugeIcon(
icon: HugeIcons.strokeRoundedPencilEdit02,
color: colorScheme.textBase,
size: 20,
),
label: context.l10n.edit,
isFirst: itemIndex == 0,
isLast: itemIndex == totalItems - 1,
),
),
);
itemIndex++;

items.add(
PopupMenuItem<String>(
value: 'delete',
padding: EdgeInsets.zero,
height: 0,
child: PopupMenuItemWidget(
icon: HugeIcon(
icon: HugeIcons.strokeRoundedDelete02,
color: colorScheme.warning500,
size: 20,
),
isWarning: true,
label: context.l10n.delete,
isFirst: itemIndex == 0,
isLast: itemIndex == totalItems - 1,
),
),
);
}

if (collectionViewType == CollectionViewType.sharedCollectionViewer ||
collectionViewType ==
CollectionViewType.sharedCollectionCollaborator) {
items.add(
PopupMenuItem<String>(
value: 'leave_collection',
padding: EdgeInsets.zero,
height: 0,
child: PopupMenuItemWidget(
icon: HugeIcon(
icon: HugeIcons.strokeRoundedDelete02,
color: colorScheme.textBase,
size: 20,
),
label: context.l10n.leaveCollection,
isFirst: true,
isLast: true,
),
),
);
}

return items;
},
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ class AccountSettingsPage extends StatelessWidget {
CryptoUtil.bin2hex(Configuration.instance.getRecoveryKey());
} catch (e) {
// ignore: unawaited_futures
showGenericErrorDialog(
showGenericErrorBottomSheet(
context: context,
error: e,
);
Expand Down
Loading
Loading