upload_icon_widget.dart 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. import "dart:async";
  2. import "package:flutter/material.dart";
  3. import "package:flutter_animate/flutter_animate.dart";
  4. import "package:photos/core/event_bus.dart";
  5. import "package:photos/db/files_db.dart";
  6. import "package:photos/events/collection_updated_event.dart";
  7. import "package:photos/events/files_updated_event.dart";
  8. import "package:photos/models/file.dart";
  9. import "package:photos/services/collections_service.dart";
  10. import "package:photos/services/hidden_service.dart";
  11. import "package:photos/services/ignored_files_service.dart";
  12. import "package:photos/services/remote_sync_service.dart";
  13. import "package:photos/theme/ente_theme.dart";
  14. class UploadIconWidget extends StatefulWidget {
  15. final File file;
  16. const UploadIconWidget({super.key, required this.file});
  17. @override
  18. State<StatefulWidget> createState() {
  19. return _UpdateIconWidgetState();
  20. }
  21. }
  22. class _UpdateIconWidgetState extends State<UploadIconWidget> {
  23. late StreamSubscription<CollectionUpdatedEvent> _firstImportEvent;
  24. bool isUploadedNow = false;
  25. @override
  26. void initState() {
  27. super.initState();
  28. _firstImportEvent =
  29. Bus.instance.on<CollectionUpdatedEvent>().listen((event) {
  30. if (mounted &&
  31. event.type == EventType.addedOrUpdated &&
  32. event.updatedFiles.isNotEmpty &&
  33. event.updatedFiles.first.localID == widget.file.localID &&
  34. event.updatedFiles.first.isUploaded) {
  35. setState(() {
  36. isUploadedNow = true;
  37. });
  38. }
  39. });
  40. }
  41. @override
  42. void dispose() {
  43. _firstImportEvent.cancel();
  44. super.dispose();
  45. }
  46. @override
  47. Widget build(BuildContext context) {
  48. if (widget.file.isUploaded || isUploadedNow) {
  49. if (isUploadedNow) {
  50. final colorScheme = getEnteColorScheme(context);
  51. return Padding(
  52. padding: const EdgeInsets.all(8.0),
  53. child: Icon(
  54. Icons.cloud_done_outlined,
  55. color: colorScheme.primary700,
  56. )
  57. .animate()
  58. .fadeIn(
  59. duration: 500.ms,
  60. curve: Curves.easeInOutCubic,
  61. )
  62. .fadeOut(
  63. delay: const Duration(seconds: 5),
  64. duration: 500.ms,
  65. curve: Curves.easeInOutCubic,
  66. ),
  67. );
  68. }
  69. return const SizedBox.shrink();
  70. }
  71. return FutureBuilder<bool>(
  72. future: IgnoredFilesService.instance.shouldSkipUploadAsync(widget.file),
  73. builder: (context, snapshot) {
  74. if (snapshot.hasData) {
  75. final bool isIgnored = snapshot.data!;
  76. final bool isQueuedForUpload =
  77. !isIgnored && widget.file.collectionID != null;
  78. return IconButton(
  79. icon: Icon(
  80. isQueuedForUpload
  81. ? Icons.cloud_upload_outlined
  82. : Icons.upload_rounded,
  83. color: Colors.white,
  84. ),
  85. onPressed: () async {
  86. if (isIgnored) {
  87. await IgnoredFilesService.instance
  88. .removeIgnoredMappings([widget.file]);
  89. }
  90. if (widget.file.collectionID == null) {
  91. widget.file.collectionID = (await CollectionsService.instance
  92. .getUncategorizedCollection())
  93. .id;
  94. FilesDB.instance.insert(widget.file);
  95. }
  96. RemoteSyncService.instance.sync().ignore();
  97. if (mounted) {
  98. setState(() {});
  99. }
  100. },
  101. );
  102. } else {
  103. return const SizedBox.shrink();
  104. }
  105. },
  106. );
  107. }
  108. }