More cleanup
This commit is contained in:
parent
6f81cac8e5
commit
ce63fc6768
14 changed files with 403 additions and 393 deletions
|
@ -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,
|
||||
});
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
),
|
||||
);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
113
lib/ui/tabs/shared/incoming_album_item.dart
Normal file
113
lib/ui/tabs/shared/incoming_album_item.dart
Normal 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",
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
116
lib/ui/tabs/shared/outgoing_album_item.dart
Normal file
116
lib/ui/tabs/shared/outgoing_album_item.dart
Normal 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);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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",
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
Loading…
Add table
Reference in a new issue