More cleanup

This commit is contained in:
Neeraj Gupta 2023-06-06 22:13:32 +05:30
parent 6f81cac8e5
commit ce63fc6768
14 changed files with 403 additions and 393 deletions

View file

@ -9,10 +9,10 @@ import 'package:photos/ui/viewer/file/no_thumbnail_widget.dart';
import 'package:photos/ui/viewer/file/thumbnail_widget.dart';
///https://www.figma.com/file/SYtMyLBs5SAOkTbfMMzhqt/ente-Visual-Design?node-id=7480%3A33462&t=H5AvR79OYDnB9ekw-4
class AlbumListItemWidget extends StatelessWidget {
class AlbumColumnItemWidget extends StatelessWidget {
final CollectionWithThumbnail item;
const AlbumListItemWidget(
const AlbumColumnItemWidget(
this.item, {
super.key,
});

View file

@ -7,7 +7,7 @@ import "package:photos/events/collection_updated_event.dart";
import "package:photos/generated/l10n.dart";
import "package:photos/models/collection_items.dart";
import "package:photos/theme/ente_theme.dart";
import "package:photos/ui/collections/collection_item_widget.dart";
import "package:photos/ui/collections/album/row_item.dart";
import "package:photos/ui/common/loading_widget.dart";
class AlbumHorizontalList extends StatefulWidget {
@ -83,7 +83,7 @@ class _AlbumHorizontalListState extends State<AlbumHorizontalList> {
padding: const EdgeInsets.symmetric(horizontal: 8),
itemBuilder: (context, index) {
final item = collectionsWithThumbnail[index];
return CollectionItem(
return AlbumRowItemWidget(
item,
120,
shouldRender: true,

View file

@ -12,13 +12,13 @@ import 'package:photos/ui/viewer/gallery/collection_page.dart';
import 'package:photos/utils/navigation_util.dart';
import 'package:visibility_detector/visibility_detector.dart';
class CollectionItem extends StatelessWidget {
class AlbumRowItemWidget extends StatelessWidget {
final CollectionWithThumbnail c;
final double sideOfThumbnail;
final bool shouldRender;
final bool showFileCount;
CollectionItem(
AlbumRowItemWidget(
this.c,
this.sideOfThumbnail, {
this.shouldRender = false,

View file

@ -16,9 +16,9 @@ import 'package:photos/services/collections_service.dart';
import 'package:photos/services/ignored_files_service.dart';
import 'package:photos/services/remote_sync_service.dart';
import "package:photos/ui/actions/collection/collection_sharing_actions.dart";
import "package:photos/ui/collections/album/list_item.dart";
import "package:photos/ui/collections/album/column_item.dart";
import "package:photos/ui/collections/album/new_list_item.dart";
import 'package:photos/ui/collections/collection_action_sheet.dart';
import 'package:photos/ui/components/new_album_list_widget.dart';
import "package:photos/ui/sharing/share_collection_page.dart";
import 'package:photos/ui/viewer/gallery/collection_page.dart';
import "package:photos/ui/viewer/gallery/empty_state.dart";
@ -28,7 +28,7 @@ import 'package:photos/utils/share_util.dart';
import 'package:photos/utils/toast_util.dart';
import 'package:receive_sharing_intent/receive_sharing_intent.dart';
class CollectionsListWidget extends StatelessWidget {
class AlbumVerticalListWidget extends StatelessWidget {
final List<CollectionWithThumbnail> collectionsWithThumbnail;
final CollectionActionType actionType;
final SelectedFiles? selectedFiles;
@ -36,7 +36,7 @@ class CollectionsListWidget extends StatelessWidget {
final String searchQuery;
final bool shouldShowCreateAlbum;
CollectionsListWidget(
AlbumVerticalListWidget(
this.collectionsWithThumbnail,
this.actionType,
this.selectedFiles,
@ -70,7 +70,7 @@ class CollectionsListWidget extends StatelessWidget {
return GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () => _albumListItemOnTap(context, item),
child: AlbumListItemWidget(
child: AlbumColumnItemWidget(
item,
),
);

View file

@ -7,10 +7,10 @@ import "package:photos/services/collections_service.dart";
import 'package:photos/ui/viewer/gallery/archive_page.dart';
import 'package:photos/utils/navigation_util.dart';
class ArchivedCollectionsButtonWidget extends StatelessWidget {
class ArchivedCollectionsButton extends StatelessWidget {
final TextStyle textStyle;
const ArchivedCollectionsButtonWidget(
const ArchivedCollectionsButton(
this.textStyle, {
Key? key,
}) : super(key: key);

View file

@ -8,8 +8,8 @@ import "package:photos/generated/l10n.dart";
import 'package:photos/ui/viewer/gallery/trash_page.dart';
import 'package:photos/utils/navigation_util.dart';
class TrashButtonWidget extends StatefulWidget {
const TrashButtonWidget(
class TrashSectionButton extends StatefulWidget {
const TrashSectionButton(
this.textStyle, {
Key? key,
}) : super(key: key);
@ -17,10 +17,10 @@ class TrashButtonWidget extends StatefulWidget {
final TextStyle textStyle;
@override
State<TrashButtonWidget> createState() => _TrashButtonWidgetState();
State<TrashSectionButton> createState() => _TrashSectionButtonState();
}
class _TrashButtonWidgetState extends State<TrashButtonWidget> {
class _TrashSectionButtonState extends State<TrashSectionButton> {
late StreamSubscription<TrashUpdatedEvent> _trashUpdatedEventSubscription;
@override

View file

@ -8,10 +8,10 @@ import 'package:photos/services/hidden_service.dart';
import 'package:photos/ui/viewer/gallery/uncategorized_page.dart';
import 'package:photos/utils/navigation_util.dart';
class UnCatCollectionsButtonWidget extends StatelessWidget {
class UnCategorizedCollections extends StatelessWidget {
final TextStyle textStyle;
const UnCatCollectionsButtonWidget(
const UnCategorizedCollections(
this.textStyle, {
Key? key,
}) : super(key: key);

View file

@ -12,7 +12,7 @@ import 'package:photos/models/selected_files.dart';
import 'package:photos/services/collections_service.dart';
import 'package:photos/theme/colors.dart';
import 'package:photos/theme/ente_theme.dart';
import 'package:photos/ui/collections/collections_list_widget.dart';
import 'package:photos/ui/collections/album/vertical_list.dart';
import 'package:photos/ui/common/loading_widget.dart';
import 'package:photos/ui/components/bottom_of_title_bar_widget.dart';
import 'package:photos/ui/components/buttons/button_widget.dart';
@ -229,7 +229,7 @@ class _CollectionActionSheetState extends State<CollectionActionSheet> {
radius: const Radius.circular(2),
child: Padding(
padding: const EdgeInsets.only(right: 12),
child: CollectionsListWidget(
child: AlbumVerticalListWidget(
searchResults,
widget.actionType,
widget.selectedFiles,

View file

@ -2,7 +2,7 @@ import 'dart:math';
import 'package:flutter/material.dart';
import 'package:photos/models/collection_items.dart';
import 'package:photos/ui/collections/collection_item_widget.dart';
import "package:photos/ui/collections/album/row_item.dart";
import 'package:photos/ui/collections/create_new_album_widget.dart';
class RemoteCollectionsGridViewWidget extends StatelessWidget {
@ -46,7 +46,7 @@ class RemoteCollectionsGridViewWidget extends StatelessWidget {
// to disable GridView's scrolling
itemBuilder: (context, index) {
if (index < collections!.length) {
return CollectionItem(
return AlbumRowItemWidget(
collections![index],
sideOfThumbnail,
shouldRender: index < collectionItemsToPreload,

View file

@ -1,29 +1,19 @@
import "package:flutter/material.dart";
import "package:photos/core/constants.dart";
import "package:fluttertoast/fluttertoast.dart";
import "package:photos/core/event_bus.dart";
import "package:photos/events/tab_changed_event.dart";
import "package:photos/generated/l10n.dart";
import "package:photos/theme/ente_theme.dart";
import 'package:photos/ui/collections/collection_action_sheet.dart';
import "package:photos/ui/common/gradient_button.dart";
import 'package:photos/ui/components/buttons/button_widget.dart';
import "package:photos/ui/components/empty_state_item_widget.dart";
import "package:photos/ui/components/models/button_type.dart";
import "package:photos/utils/share_util.dart";
import "package:photos/utils/toast_util.dart";
class NewSharedCollectionsGallery extends StatelessWidget {
const NewSharedCollectionsGallery({super.key});
@override
Widget build(BuildContext context) {
return Center(
child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: restrictedMaxWidth),
child: const EmptyStateWidget(),
),
);
}
}
class EmptyStateWidget extends StatelessWidget {
const EmptyStateWidget({super.key});
class SharedEmptyStateWidget extends StatelessWidget {
const SharedEmptyStateWidget({super.key});
@override
Widget build(BuildContext context) {
@ -117,3 +107,76 @@ class EmptyStateWidget extends StatelessWidget {
);
}
}
class OutgoingAlbumEmptyState extends StatelessWidget {
const OutgoingAlbumEmptyState({super.key});
@override
Widget build(BuildContext context) {
return SizedBox(
height: 200,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
S.of(context).shareYourFirstAlbum,
style: Theme.of(context).textTheme.caption,
),
const Padding(padding: EdgeInsets.only(top: 14)),
SizedBox(
width: 200,
height: 50,
child: GradientButton(
onTap: () async {
await showToast(
context,
S.of(context).shareAlbumHint,
toastLength: Toast.LENGTH_LONG,
);
Bus.instance.fire(
TabChangedEvent(1, TabChangedEventSource.collectionsPage),
);
},
iconData: Icons.person_add,
text: S.of(context).share,
),
),
const SizedBox(height: 60),
],
),
);
}
}
class IncomingAlbumEmptyState extends StatelessWidget {
const IncomingAlbumEmptyState({super.key});
@override
Widget build(BuildContext context) {
return SizedBox(
height: 220,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
S.of(context).askYourLovedOnesToShare,
style: Theme.of(context).textTheme.caption,
),
const Padding(padding: EdgeInsets.only(top: 14)),
SizedBox(
width: 200,
height: 50,
child: GradientButton(
onTap: () async {
shareText(S.of(context).shareTextRecommendUsingEnte);
},
iconData: Icons.outgoing_mail,
text: S.of(context).invite,
),
),
const SizedBox(height: 60),
],
),
);
}
}

View file

@ -0,0 +1,113 @@
import "dart:math";
import "package:flutter/material.dart";
import "package:photos/db/files_db.dart";
import "package:photos/models/collection_items.dart";
import "package:photos/models/gallery_type.dart";
import "package:photos/ui/sharing/user_avator_widget.dart";
import "package:photos/ui/viewer/file/thumbnail_widget.dart";
import "package:photos/ui/viewer/gallery/collection_page.dart";
import "package:photos/utils/navigation_util.dart";
class IncomingAlbumItem extends StatelessWidget {
final CollectionWithThumbnail c;
const IncomingAlbumItem(
this.c, {
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
const double horizontalPaddingOfGridRow = 16;
const double crossAxisSpacingOfGrid = 9;
final TextStyle albumTitleTextStyle =
Theme.of(context).textTheme.subtitle1!.copyWith(fontSize: 14);
final Size size = MediaQuery.of(context).size;
final int albumsCountInOneRow = max(size.width ~/ 220.0, 2);
final double totalWhiteSpaceOfRow = (horizontalPaddingOfGridRow * 2) +
(albumsCountInOneRow - 1) * crossAxisSpacingOfGrid;
final double sideOfThumbnail = (size.width / albumsCountInOneRow) -
(totalWhiteSpaceOfRow / albumsCountInOneRow);
return GestureDetector(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
ClipRRect(
borderRadius: BorderRadius.circular(1),
child: SizedBox(
height: sideOfThumbnail,
width: sideOfThumbnail,
child: Stack(
children: [
Hero(
tag: "shared_collection" + c.thumbnail!.tag,
child: ThumbnailWidget(
c.thumbnail,
key: Key("shared_collection" + c.thumbnail!.tag),
shouldShowArchiveStatus: c.collection.hasShareeArchived(),
shouldShowSyncStatus: false,
),
),
Align(
alignment: Alignment.bottomRight,
child: Padding(
padding: const EdgeInsets.only(right: 8.0, bottom: 8.0),
child: UserAvatarWidget(
c.collection.owner!,
thumbnailView: true,
),
),
),
],
),
),
),
const SizedBox(height: 4),
Row(
children: [
Container(
constraints: BoxConstraints(maxWidth: sideOfThumbnail - 40),
child: Text(
c.collection.displayName,
style: albumTitleTextStyle,
overflow: TextOverflow.ellipsis,
),
),
FutureBuilder<int>(
future: FilesDB.instance.collectionFileCount(c.collection.id),
builder: (context, snapshot) {
if (snapshot.hasData && snapshot.data! > 0) {
return RichText(
text: TextSpan(
style: albumTitleTextStyle.copyWith(
color: albumTitleTextStyle.color!.withOpacity(0.5),
),
children: [
const TextSpan(text: " \u2022 "),
TextSpan(text: snapshot.data.toString()),
],
),
);
} else {
return Container();
}
},
),
],
),
],
),
onTap: () {
routeToPage(
context,
CollectionPage(
c,
appBarType: GalleryType.sharedCollection,
tagPrefix: "shared_collection",
),
);
},
);
}
}

View file

@ -0,0 +1,116 @@
import "package:flutter/material.dart";
import "package:photos/generated/l10n.dart";
import "package:photos/models/collection_items.dart";
import "package:photos/models/gallery_type.dart";
import 'package:photos/theme/colors.dart';
import "package:photos/ui/viewer/file/thumbnail_widget.dart";
import "package:photos/ui/viewer/gallery/collection_page.dart";
import "package:photos/utils/navigation_util.dart";
class OutgoingAlbumItem extends StatelessWidget {
final CollectionWithThumbnail c;
const OutgoingAlbumItem({super.key, required this.c});
@override
Widget build(BuildContext context) {
final shareesName = <String>[];
if (c.collection.hasSharees) {
for (int index = 0; index < c.collection.sharees!.length; index++) {
final sharee = c.collection.sharees![index]!;
final String name =
(sharee.name?.isNotEmpty ?? false) ? sharee.name! : sharee.email;
if (index < 2) {
shareesName.add(name);
} else {
final remaining = c.collection.sharees!.length - index;
if (remaining == 1) {
// If it's the last sharee
shareesName.add(name);
} else {
shareesName.add(
"and " +
remaining.toString() +
" other" +
(remaining > 1 ? "s" : ""),
);
}
break;
}
}
}
return GestureDetector(
behavior: HitTestBehavior.opaque,
child: Container(
margin: const EdgeInsets.fromLTRB(16, 12, 16, 12),
child: Row(
children: <Widget>[
ClipRRect(
borderRadius: BorderRadius.circular(1),
child: SizedBox(
height: 60,
width: 60,
child: Hero(
tag: "outgoing_collection" + c.thumbnail!.tag,
child: ThumbnailWidget(
c.thumbnail,
key: Key("outgoing_collection" + c.thumbnail!.tag),
),
),
),
),
const Padding(padding: EdgeInsets.all(8)),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Text(
c.collection.displayName,
style: const TextStyle(
fontSize: 16,
),
),
const Padding(padding: EdgeInsets.all(2)),
c.collection.hasLink
? (c.collection.publicURLs!.first!.isExpired
? const Icon(
Icons.link,
color: warning500,
)
: const Icon(Icons.link))
: Container(),
],
),
shareesName.isEmpty
? Container()
: Padding(
padding: const EdgeInsets.fromLTRB(0, 4, 0, 0),
child: Text(
S.of(context).sharedWith(shareesName.join(", ")),
style: TextStyle(
fontSize: 14,
color: Theme.of(context).primaryColorLight,
),
textAlign: TextAlign.left,
overflow: TextOverflow.ellipsis,
),
),
],
),
),
],
),
),
onTap: () {
final page = CollectionPage(
c,
appBarType: GalleryType.ownedCollection,
tagPrefix: "outgoing_collection",
);
routeToPage(context, page);
},
);
}
}

View file

@ -2,31 +2,22 @@ import 'dart:async';
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:logging/logging.dart';
import 'package:photos/core/configuration.dart';
import 'package:photos/core/event_bus.dart';
import 'package:photos/db/files_db.dart';
import 'package:photos/events/collection_updated_event.dart';
import 'package:photos/events/local_photos_updated_event.dart';
import 'package:photos/events/tab_changed_event.dart';
import 'package:photos/events/user_logged_out_event.dart';
import "package:photos/generated/l10n.dart";
import 'package:photos/models/collection.dart';
import 'package:photos/models/collection_items.dart';
import 'package:photos/models/gallery_type.dart';
import "package:photos/models/file.dart";
import 'package:photos/services/collections_service.dart';
import 'package:photos/theme/colors.dart';
import 'package:photos/ui/collections/section_title.dart';
import 'package:photos/ui/common/gradient_button.dart';
import 'package:photos/ui/common/loading_widget.dart';
import "package:photos/ui/sharing/user_avator_widget.dart";
import 'package:photos/ui/tabs/shared/new_shared_collections_gallery.dart';
import 'package:photos/ui/viewer/file/thumbnail_widget.dart';
import 'package:photos/ui/viewer/gallery/collection_page.dart';
import 'package:photos/utils/navigation_util.dart';
import 'package:photos/utils/share_util.dart';
import 'package:photos/utils/toast_util.dart';
import 'package:photos/ui/tabs/section_title.dart';
import "package:photos/ui/tabs/shared/empty_state.dart";
import "package:photos/ui/tabs/shared/incoming_album_item.dart";
import "package:photos/ui/tabs/shared/outgoing_album_item.dart";
class SharedCollectionsTab extends StatefulWidget {
const SharedCollectionsTab({Key? key}) : super(key: key);
@ -68,64 +59,13 @@ class _SharedCollectionsTabState extends State<SharedCollectionsTab>
future:
Future.value(CollectionsService.instance.getLatestCollectionFiles())
.then((files) async {
final List<CollectionWithThumbnail> outgoing = [];
final List<CollectionWithThumbnail> incoming = [];
for (final file in files) {
if (file.collectionID == null) {
_logger.severe("collection id should not be null");
continue;
}
final Collection? c =
CollectionsService.instance.getCollectionByID(file.collectionID!);
if (c == null) {
_logger
.severe("shared collection is not cached ${file.collectionID}");
CollectionsService.instance
.fetchCollectionByID(file.collectionID!)
.ignore();
continue;
}
if (c.owner!.id == Configuration.instance.getUserID()) {
if (c.hasSharees || c.hasLink || c.isSharedFilesCollection()) {
outgoing.add(
CollectionWithThumbnail(
c,
file,
),
);
}
} else {
incoming.add(
CollectionWithThumbnail(
c,
file,
),
);
}
}
outgoing.sort((first, second) {
if (second.collection.isSharedFilesCollection() ==
first.collection.isSharedFilesCollection()) {
return second.collection.updationTime
.compareTo(first.collection.updationTime);
} else {
if (first.collection.isSharedFilesCollection()) {
return 1;
}
return -1;
}
});
incoming.sort((first, second) {
return second.collection.updationTime
.compareTo(first.collection.updationTime);
});
return SharedCollections(outgoing, incoming);
return _getSharedCollections(files);
}),
builder: (context, snapshot) {
if (snapshot.hasData) {
if ((snapshot.data?.incoming.length ?? 0) == 0 &&
(snapshot.data?.outgoing.length ?? 0) == 0) {
return const Center(child: EmptyStateWidget());
return const Center(child: SharedEmptyStateWidget());
}
return _getSharedCollectionsGallery(snapshot.data!);
} else if (snapshot.hasError) {
@ -164,9 +104,10 @@ class _SharedCollectionsTabState extends State<SharedCollectionsTab>
padding: const EdgeInsets.symmetric(horizontal: 16),
child: GridView.builder(
shrinkWrap: true,
scrollDirection: Axis.vertical,
physics: const NeverScrollableScrollPhysics(),
itemBuilder: (context, index) {
return IncomingCollectionItem(
return IncomingAlbumItem(
collections.incoming[index],
);
},
@ -180,7 +121,7 @@ class _SharedCollectionsTabState extends State<SharedCollectionsTab>
), //24 is height of album title
),
)
: _getIncomingCollectionEmptyState(),
: const IncomingAlbumEmptyState(),
const SizedBox(height: 16),
SectionTitle(title: S.of(context).sharedByMe),
const SizedBox(height: 12),
@ -190,13 +131,13 @@ class _SharedCollectionsTabState extends State<SharedCollectionsTab>
padding: const EdgeInsets.only(bottom: 12),
physics: const NeverScrollableScrollPhysics(),
itemBuilder: (context, index) {
return OutgoingCollectionItem(
collections.outgoing[index],
return OutgoingAlbumItem(
c: collections.outgoing[index],
);
},
itemCount: collections.outgoing.length,
)
: _getOutgoingCollectionEmptyState(),
: const OutgoingAlbumEmptyState(),
const SizedBox(height: 32),
],
),
@ -204,67 +145,58 @@ class _SharedCollectionsTabState extends State<SharedCollectionsTab>
);
}
Widget _getIncomingCollectionEmptyState() {
return SizedBox(
height: 220,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
S.of(context).askYourLovedOnesToShare,
style: Theme.of(context).textTheme.caption,
),
const Padding(padding: EdgeInsets.only(top: 14)),
SizedBox(
width: 200,
height: 50,
child: GradientButton(
onTap: () async {
shareText(S.of(context).shareTextRecommendUsingEnte);
},
iconData: Icons.outgoing_mail,
text: S.of(context).invite,
SharedCollections _getSharedCollections(List<File> recentFileForCollections) {
final List<CollectionWithThumbnail> outgoing = [];
final List<CollectionWithThumbnail> incoming = [];
for (final file in recentFileForCollections) {
if (file.collectionID == null) {
_logger.severe("collection id should not be null");
continue;
}
final Collection? c =
CollectionsService.instance.getCollectionByID(file.collectionID!);
if (c == null) {
_logger.severe("shared collection is not cached ${file.collectionID}");
CollectionsService.instance
.fetchCollectionByID(file.collectionID!)
.ignore();
continue;
}
if (c.owner!.id == Configuration.instance.getUserID()) {
if (c.hasSharees || c.hasLink || c.isSharedFilesCollection()) {
outgoing.add(
CollectionWithThumbnail(
c,
file,
),
);
}
} else {
incoming.add(
CollectionWithThumbnail(
c,
file,
),
const SizedBox(height: 60),
],
),
);
}
Widget _getOutgoingCollectionEmptyState() {
return SizedBox(
height: 200,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
S.of(context).shareYourFirstAlbum,
style: Theme.of(context).textTheme.caption,
),
const Padding(padding: EdgeInsets.only(top: 14)),
SizedBox(
width: 200,
height: 50,
child: GradientButton(
onTap: () async {
await showToast(
context,
S.of(context).shareAlbumHint,
toastLength: Toast.LENGTH_LONG,
);
Bus.instance.fire(
TabChangedEvent(1, TabChangedEventSource.collectionsPage),
);
},
iconData: Icons.person_add,
text: S.of(context).share,
),
),
const SizedBox(height: 60),
],
),
);
);
}
}
outgoing.sort((first, second) {
if (second.collection.isSharedFilesCollection() ==
first.collection.isSharedFilesCollection()) {
return second.collection.updationTime
.compareTo(first.collection.updationTime);
} else {
if (first.collection.isSharedFilesCollection()) {
return 1;
}
return -1;
}
});
incoming.sort((first, second) {
return second.collection.updationTime
.compareTo(first.collection.updationTime);
});
return SharedCollections(outgoing, incoming);
}
@override
@ -278,217 +210,3 @@ class _SharedCollectionsTabState extends State<SharedCollectionsTab>
@override
bool get wantKeepAlive => true;
}
class OutgoingCollectionItem extends StatelessWidget {
final CollectionWithThumbnail c;
const OutgoingCollectionItem(
this.c, {
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
final shareesName = <String>[];
if (c.collection.hasSharees) {
for (int index = 0; index < c.collection.sharees!.length; index++) {
final sharee = c.collection.sharees![index]!;
final String name =
(sharee.name?.isNotEmpty ?? false) ? sharee.name! : sharee.email;
if (index < 2) {
shareesName.add(name);
} else {
final remaining = c.collection.sharees!.length - index;
if (remaining == 1) {
// If it's the last sharee
shareesName.add(name);
} else {
shareesName.add(
"and " +
remaining.toString() +
" other" +
(remaining > 1 ? "s" : ""),
);
}
break;
}
}
}
return GestureDetector(
behavior: HitTestBehavior.opaque,
child: Container(
margin: const EdgeInsets.fromLTRB(16, 12, 16, 12),
child: Row(
children: <Widget>[
ClipRRect(
borderRadius: BorderRadius.circular(1),
child: SizedBox(
height: 60,
width: 60,
child: Hero(
tag: "outgoing_collection" + c.thumbnail!.tag,
child: ThumbnailWidget(
c.thumbnail,
key: Key("outgoing_collection" + c.thumbnail!.tag),
),
),
),
),
const Padding(padding: EdgeInsets.all(8)),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Text(
c.collection.displayName,
style: const TextStyle(
fontSize: 16,
),
),
const Padding(padding: EdgeInsets.all(2)),
c.collection.hasLink
? (c.collection.publicURLs!.first!.isExpired
? const Icon(
Icons.link,
color: warning500,
)
: const Icon(Icons.link))
: Container(),
],
),
shareesName.isEmpty
? Container()
: Padding(
padding: const EdgeInsets.fromLTRB(0, 4, 0, 0),
child: Text(
S.of(context).sharedWith(shareesName.join(", ")),
style: TextStyle(
fontSize: 14,
color: Theme.of(context).primaryColorLight,
),
textAlign: TextAlign.left,
overflow: TextOverflow.ellipsis,
),
),
],
),
),
],
),
),
onTap: () {
final page = CollectionPage(
c,
appBarType: GalleryType.ownedCollection,
tagPrefix: "outgoing_collection",
);
routeToPage(context, page);
},
);
}
}
class IncomingCollectionItem extends StatelessWidget {
final CollectionWithThumbnail c;
const IncomingCollectionItem(
this.c, {
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
const double horizontalPaddingOfGridRow = 16;
const double crossAxisSpacingOfGrid = 9;
final TextStyle albumTitleTextStyle =
Theme.of(context).textTheme.subtitle1!.copyWith(fontSize: 14);
final Size size = MediaQuery.of(context).size;
final int albumsCountInOneRow = max(size.width ~/ 220.0, 2);
final double totalWhiteSpaceOfRow = (horizontalPaddingOfGridRow * 2) +
(albumsCountInOneRow - 1) * crossAxisSpacingOfGrid;
final double sideOfThumbnail = (size.width / albumsCountInOneRow) -
(totalWhiteSpaceOfRow / albumsCountInOneRow);
return GestureDetector(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
ClipRRect(
borderRadius: BorderRadius.circular(1),
child: SizedBox(
height: sideOfThumbnail,
width: sideOfThumbnail,
child: Stack(
children: [
Hero(
tag: "shared_collection" + c.thumbnail!.tag,
child: ThumbnailWidget(
c.thumbnail,
key: Key("shared_collection" + c.thumbnail!.tag),
shouldShowArchiveStatus: c.collection.hasShareeArchived(),
shouldShowSyncStatus: false,
),
),
Align(
alignment: Alignment.bottomRight,
child: Padding(
padding: const EdgeInsets.only(right: 8.0, bottom: 8.0),
child: UserAvatarWidget(
c.collection.owner!,
thumbnailView: true,
),
),
),
],
),
),
),
const SizedBox(height: 4),
Row(
children: [
Container(
constraints: BoxConstraints(maxWidth: sideOfThumbnail - 40),
child: Text(
c.collection.displayName,
style: albumTitleTextStyle,
overflow: TextOverflow.ellipsis,
),
),
FutureBuilder<int>(
future: FilesDB.instance.collectionFileCount(c.collection.id),
builder: (context, snapshot) {
if (snapshot.hasData && snapshot.data! > 0) {
return RichText(
text: TextSpan(
style: albumTitleTextStyle.copyWith(
color: albumTitleTextStyle.color!.withOpacity(0.5),
),
children: [
const TextSpan(text: " \u2022 "),
TextSpan(text: snapshot.data.toString()),
],
),
);
} else {
return Container();
}
},
),
],
),
],
),
onTap: () {
routeToPage(
context,
CollectionPage(
c,
appBarType: GalleryType.sharedCollection,
tagPrefix: "shared_collection",
),
);
},
);
}
}

View file

@ -15,15 +15,15 @@ import 'package:photos/models/collection.dart';
import 'package:photos/models/collection_items.dart';
import 'package:photos/services/collections_service.dart';
import "package:photos/services/remote_sync_service.dart";
import 'package:photos/ui/collections/archived_collections_button_widget.dart';
import "package:photos/ui/collections/button/archived_button.dart";
import "package:photos/ui/collections/button/hidden_button.dart";
import "package:photos/ui/collections/button/trash_button.dart";
import "package:photos/ui/collections/button/uncategorized_button.dart";
import 'package:photos/ui/collections/device_folders_grid_view_widget.dart';
import 'package:photos/ui/collections/hidden_collections_button_widget.dart';
import 'package:photos/ui/collections/remote_collections_grid_view_widget.dart';
import 'package:photos/ui/collections/section_title.dart';
import 'package:photos/ui/collections/trash_button_widget.dart';
import 'package:photos/ui/collections/uncat_collections_button_widget.dart';
import 'package:photos/ui/common/loading_widget.dart';
import 'package:photos/ui/components/buttons/icon_button_widget.dart';
import 'package:photos/ui/tabs/section_title.dart';
import 'package:photos/ui/viewer/actions/delete_empty_albums.dart';
import 'package:photos/ui/viewer/gallery/empty_state.dart';
import 'package:photos/utils/local_settings.dart';
@ -173,13 +173,13 @@ class _UserCollectionsTabState extends State<UserCollectionsTab>
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Column(
children: [
UnCatCollectionsButtonWidget(trashAndHiddenTextStyle),
UnCategorizedCollections(trashAndHiddenTextStyle),
const SizedBox(height: 12),
ArchivedCollectionsButtonWidget(trashAndHiddenTextStyle),
ArchivedCollectionsButton(trashAndHiddenTextStyle),
const SizedBox(height: 12),
HiddenCollectionsButtonWidget(trashAndHiddenTextStyle),
const SizedBox(height: 12),
TrashButtonWidget(trashAndHiddenTextStyle),
TrashSectionButton(trashAndHiddenTextStyle),
],
),
),