current_backup_asset_info_box.dart 7.0 KB

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