current_backup_asset_info_box.dart 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. import 'package:easy_localization/easy_localization.dart';
  2. import 'package:flutter/foundation.dart';
  3. import 'package:flutter/material.dart';
  4. import 'package:flutter_hooks/flutter_hooks.dart';
  5. import 'package:hooks_riverpod/hooks_riverpod.dart';
  6. import 'package:immich_mobile/extensions/build_context_extensions.dart';
  7. import 'package:immich_mobile/modules/backup/models/backup_state.model.dart';
  8. import 'package:immich_mobile/modules/backup/providers/backup.provider.dart';
  9. import 'package:immich_mobile/modules/backup/providers/error_backup_list.provider.dart';
  10. import 'package:immich_mobile/modules/backup/providers/manual_upload.provider.dart';
  11. import 'package:immich_mobile/routing/router.dart';
  12. import 'package:photo_manager/photo_manager.dart';
  13. class CurrentUploadingAssetInfoBox extends HookConsumerWidget {
  14. const CurrentUploadingAssetInfoBox({super.key});
  15. @override
  16. Widget build(BuildContext context, WidgetRef ref) {
  17. var isManualUpload = ref.watch(backupProvider).backupProgress ==
  18. BackUpProgressEnum.manualInProgress;
  19. var asset = !isManualUpload
  20. ? ref.watch(backupProvider).currentUploadAsset
  21. : ref.watch(manualUploadProvider).currentUploadAsset;
  22. var uploadProgress = !isManualUpload
  23. ? ref.watch(backupProvider).progressInPercentage
  24. : ref.watch(manualUploadProvider).progressInPercentage;
  25. final isShowThumbnail = useState(false);
  26. String getAssetCreationDate() {
  27. return DateFormat.yMMMMd().format(
  28. DateTime.parse(
  29. asset.fileCreatedAt.toString(),
  30. ).toLocal(),
  31. );
  32. }
  33. Widget buildErrorChip() {
  34. return ActionChip(
  35. avatar: Icon(
  36. Icons.info,
  37. color: Colors.red[400],
  38. ),
  39. elevation: 1,
  40. visualDensity: VisualDensity.compact,
  41. label: Text(
  42. "backup_controller_page_failed",
  43. style: TextStyle(
  44. color: Colors.red[400],
  45. fontWeight: FontWeight.bold,
  46. fontSize: 11,
  47. ),
  48. ).tr(
  49. args: [ref.watch(errorBackupListProvider).length.toString()],
  50. ),
  51. backgroundColor: Colors.white,
  52. onPressed: () {
  53. context.autoPush(const FailedBackupStatusRoute());
  54. },
  55. );
  56. }
  57. Widget buildAssetInfoTable() {
  58. return Table(
  59. border: TableBorder.all(
  60. color: context.colorScheme.onSurfaceVariant,
  61. width: 1,
  62. ),
  63. children: [
  64. TableRow(
  65. decoration: const BoxDecoration(
  66. // color: Colors.grey[100],
  67. ),
  68. children: [
  69. TableCell(
  70. verticalAlignment: TableCellVerticalAlignment.middle,
  71. child: Padding(
  72. padding: const EdgeInsets.all(6.0),
  73. child: const Text(
  74. 'backup_controller_page_filename',
  75. style: TextStyle(
  76. fontWeight: FontWeight.bold,
  77. fontSize: 10.0,
  78. ),
  79. ).tr(
  80. args: [asset.fileName, asset.fileType.toLowerCase()],
  81. ),
  82. ),
  83. ),
  84. ],
  85. ),
  86. TableRow(
  87. decoration: const BoxDecoration(
  88. // color: Colors.grey[200],
  89. ),
  90. children: [
  91. TableCell(
  92. verticalAlignment: TableCellVerticalAlignment.middle,
  93. child: Padding(
  94. padding: const EdgeInsets.all(6.0),
  95. child: const Text(
  96. "backup_controller_page_created",
  97. style: TextStyle(
  98. fontWeight: FontWeight.bold,
  99. fontSize: 10.0,
  100. ),
  101. ).tr(
  102. args: [getAssetCreationDate()],
  103. ),
  104. ),
  105. ),
  106. ],
  107. ),
  108. TableRow(
  109. decoration: const BoxDecoration(
  110. // color: Colors.grey[100],
  111. ),
  112. children: [
  113. TableCell(
  114. child: Padding(
  115. padding: const EdgeInsets.all(6.0),
  116. child: const Text(
  117. "backup_controller_page_id",
  118. style: TextStyle(
  119. fontWeight: FontWeight.bold,
  120. fontSize: 10.0,
  121. ),
  122. ).tr(args: [asset.id]),
  123. ),
  124. ),
  125. ],
  126. ),
  127. ],
  128. );
  129. }
  130. buildAssetThumbnail() async {
  131. var assetEntity = await AssetEntity.fromId(asset.id);
  132. if (assetEntity != null) {
  133. return assetEntity.thumbnailDataWithSize(
  134. const ThumbnailSize(500, 500),
  135. quality: 100,
  136. );
  137. }
  138. }
  139. return FutureBuilder<Uint8List?>(
  140. future: buildAssetThumbnail(),
  141. builder: (context, thumbnail) => ListTile(
  142. isThreeLine: true,
  143. leading: AnimatedCrossFade(
  144. alignment: Alignment.centerLeft,
  145. firstChild: GestureDetector(
  146. onTap: () => isShowThumbnail.value = false,
  147. child: thumbnail.hasData
  148. ? ClipRRect(
  149. borderRadius: BorderRadius.circular(5),
  150. child: Image.memory(
  151. thumbnail.data!,
  152. fit: BoxFit.cover,
  153. width: 50,
  154. height: 50,
  155. ),
  156. )
  157. : const SizedBox(
  158. width: 50,
  159. height: 50,
  160. child: Padding(
  161. padding: EdgeInsets.all(8.0),
  162. child: CircularProgressIndicator.adaptive(
  163. strokeWidth: 1,
  164. ),
  165. ),
  166. ),
  167. ),
  168. secondChild: GestureDetector(
  169. onTap: () => isShowThumbnail.value = true,
  170. child: Icon(
  171. Icons.image_outlined,
  172. color: context.primaryColor,
  173. size: 30,
  174. ),
  175. ),
  176. crossFadeState: isShowThumbnail.value
  177. ? CrossFadeState.showFirst
  178. : CrossFadeState.showSecond,
  179. duration: const Duration(milliseconds: 200),
  180. ),
  181. title: Row(
  182. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  183. children: [
  184. const Text(
  185. "backup_controller_page_uploading_file_info",
  186. style: TextStyle(fontWeight: FontWeight.bold, fontSize: 14),
  187. ).tr(),
  188. if (ref.watch(errorBackupListProvider).isNotEmpty) buildErrorChip(),
  189. ],
  190. ),
  191. subtitle: Column(
  192. children: [
  193. Padding(
  194. padding: const EdgeInsets.only(top: 8.0),
  195. child: Row(
  196. children: [
  197. Expanded(
  198. child: LinearProgressIndicator(
  199. minHeight: 10.0,
  200. value: uploadProgress / 100.0,
  201. backgroundColor: Colors.grey,
  202. color: context.primaryColor,
  203. ),
  204. ),
  205. Text(
  206. " ${uploadProgress.toStringAsFixed(0)}%",
  207. style: const TextStyle(fontSize: 12),
  208. ),
  209. ],
  210. ),
  211. ),
  212. Padding(
  213. padding: const EdgeInsets.only(top: 8.0),
  214. child: buildAssetInfoTable(),
  215. ),
  216. ],
  217. ),
  218. ),
  219. );
  220. }
  221. }