selection_thumbnail_image.dart 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. import 'package:cached_network_image/cached_network_image.dart';
  2. import 'package:flutter/material.dart';
  3. import 'package:flutter_hooks/flutter_hooks.dart';
  4. import 'package:hive_flutter/hive_flutter.dart';
  5. import 'package:hooks_riverpod/hooks_riverpod.dart';
  6. import 'package:immich_mobile/constants/hive_box.dart';
  7. import 'package:immich_mobile/modules/sharing/providers/asset_selection.provider.dart';
  8. import 'package:openapi/api.dart';
  9. class SelectionThumbnailImage extends HookConsumerWidget {
  10. final AssetResponseDto asset;
  11. const SelectionThumbnailImage({Key? key, required this.asset})
  12. : super(key: key);
  13. @override
  14. Widget build(BuildContext context, WidgetRef ref) {
  15. final cacheKey = useState(1);
  16. var box = Hive.box(userInfoBox);
  17. var thumbnailRequestUrl =
  18. '${box.get(serverEndpointKey)}/asset/thumbnail/${asset.id}';
  19. var selectedAsset =
  20. ref.watch(assetSelectionProvider).selectedNewAssetsForAlbum;
  21. var newAssetsForAlbum =
  22. ref.watch(assetSelectionProvider).selectedAdditionalAssetsForAlbum;
  23. var isAlbumExist = ref.watch(assetSelectionProvider).isAlbumExist;
  24. Widget _buildSelectionIcon(AssetResponseDto asset) {
  25. if (selectedAsset.contains(asset) && !isAlbumExist) {
  26. return Icon(
  27. Icons.check_circle,
  28. color: Theme.of(context).primaryColor,
  29. );
  30. } else if (selectedAsset.contains(asset) && isAlbumExist) {
  31. return const Icon(
  32. Icons.check_circle,
  33. color: Color.fromARGB(255, 233, 233, 233),
  34. );
  35. } else if (newAssetsForAlbum.contains(asset) && isAlbumExist) {
  36. return Icon(
  37. Icons.check_circle,
  38. color: Theme.of(context).primaryColor,
  39. );
  40. } else {
  41. return const Icon(
  42. Icons.circle_outlined,
  43. color: Colors.white,
  44. );
  45. }
  46. }
  47. BoxBorder drawBorderColor() {
  48. if (selectedAsset.contains(asset) && !isAlbumExist) {
  49. return Border.all(
  50. color: Theme.of(context).primaryColorLight,
  51. width: 10,
  52. );
  53. } else if (selectedAsset.contains(asset) && isAlbumExist) {
  54. return Border.all(
  55. color: const Color.fromARGB(255, 190, 190, 190),
  56. width: 10,
  57. );
  58. } else if (newAssetsForAlbum.contains(asset) && isAlbumExist) {
  59. return Border.all(
  60. color: Theme.of(context).primaryColorLight,
  61. width: 10,
  62. );
  63. }
  64. return const Border();
  65. }
  66. return GestureDetector(
  67. onTap: () {
  68. if (isAlbumExist) {
  69. // Operation for existing album
  70. if (!selectedAsset.contains(asset)) {
  71. if (newAssetsForAlbum.contains(asset)) {
  72. ref
  73. .watch(assetSelectionProvider.notifier)
  74. .removeSelectedAdditionalAssets([asset]);
  75. } else {
  76. ref
  77. .watch(assetSelectionProvider.notifier)
  78. .addAdditionalAssets([asset]);
  79. }
  80. }
  81. } else {
  82. // Operation for new album
  83. if (selectedAsset.contains(asset)) {
  84. ref
  85. .watch(assetSelectionProvider.notifier)
  86. .removeSelectedNewAssets([asset]);
  87. } else {
  88. ref.watch(assetSelectionProvider.notifier).addNewAssets([asset]);
  89. }
  90. }
  91. },
  92. child: Stack(
  93. children: [
  94. Container(
  95. decoration: BoxDecoration(border: drawBorderColor()),
  96. child: CachedNetworkImage(
  97. cacheKey: "${asset.id}-${cacheKey.value}",
  98. width: 150,
  99. height: 150,
  100. memCacheHeight: asset.type == AssetTypeEnum.IMAGE ? 150 : 150,
  101. fit: BoxFit.cover,
  102. imageUrl: thumbnailRequestUrl,
  103. httpHeaders: {
  104. "Authorization": "Bearer ${box.get(accessTokenKey)}"
  105. },
  106. fadeInDuration: const Duration(milliseconds: 250),
  107. progressIndicatorBuilder: (context, url, downloadProgress) =>
  108. Transform.scale(
  109. scale: 0.2,
  110. child:
  111. CircularProgressIndicator(value: downloadProgress.progress),
  112. ),
  113. errorWidget: (context, url, error) {
  114. return Icon(
  115. Icons.image_not_supported_outlined,
  116. color: Theme.of(context).primaryColor,
  117. );
  118. },
  119. ),
  120. ),
  121. Padding(
  122. padding: const EdgeInsets.all(3.0),
  123. child: Align(
  124. alignment: Alignment.topLeft,
  125. child: _buildSelectionIcon(asset),
  126. ),
  127. ),
  128. if (asset.type != AssetTypeEnum.IMAGE)
  129. Positioned(
  130. bottom: 5,
  131. right: 5,
  132. child: Row(
  133. children: [
  134. Text(
  135. asset.duration.substring(0, 7),
  136. style: const TextStyle(
  137. color: Colors.white,
  138. fontSize: 10,
  139. ),
  140. ),
  141. const Icon(
  142. Icons.play_circle_outline_rounded,
  143. color: Colors.white,
  144. ),
  145. ],
  146. ),
  147. ),
  148. ],
  149. ),
  150. );
  151. }
  152. }