file_icons_widget.dart 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. import 'package:flutter/material.dart';
  2. import 'package:photos/ente_theme_data.dart';
  3. import 'package:photos/models/collection.dart';
  4. import 'package:photos/models/trash_file.dart';
  5. import 'package:photos/theme/colors.dart';
  6. import 'package:photos/ui/sharing/user_avator_widget.dart';
  7. import 'package:photos/utils/date_time_util.dart';
  8. class ThumbnailPlaceHolder extends StatelessWidget {
  9. const ThumbnailPlaceHolder({Key? key}) : super(key: key);
  10. @override
  11. Widget build(BuildContext context) {
  12. return Container(
  13. alignment: Alignment.center,
  14. color: Theme.of(context).colorScheme.galleryThumbBackgroundColor,
  15. );
  16. }
  17. }
  18. class UnSyncedIcon extends StatelessWidget {
  19. const UnSyncedIcon({Key? key}) : super(key: key);
  20. @override
  21. Widget build(BuildContext context) {
  22. return const BottomLeftOverlayIcon(Icons.cloud_off_outlined);
  23. }
  24. }
  25. class FavoriteOverlayIcon extends StatelessWidget {
  26. const FavoriteOverlayIcon({Key? key}) : super(key: key);
  27. @override
  28. Widget build(BuildContext context) {
  29. return const BottomLeftOverlayIcon(
  30. Icons.favorite_rounded,
  31. baseSize: 22,
  32. );
  33. }
  34. }
  35. class ArchiveOverlayIcon extends StatelessWidget {
  36. const ArchiveOverlayIcon({Key? key}) : super(key: key);
  37. @override
  38. Widget build(BuildContext context) {
  39. return const BottomLeftOverlayIcon(
  40. Icons.archive_outlined,
  41. color: fixedStrokeMutedWhite,
  42. );
  43. }
  44. }
  45. class VideoOverlayIcon extends StatelessWidget {
  46. const VideoOverlayIcon({Key? key}) : super(key: key);
  47. @override
  48. Widget build(BuildContext context) {
  49. return const SizedBox(
  50. height: 64,
  51. child: Icon(
  52. Icons.play_circle_outline,
  53. size: 40,
  54. color: Colors.white70,
  55. ),
  56. );
  57. }
  58. }
  59. class LivePhotoOverlayIcon extends StatelessWidget {
  60. const LivePhotoOverlayIcon({Key? key}) : super(key: key);
  61. @override
  62. Widget build(BuildContext context) {
  63. return const Align(
  64. alignment: Alignment.bottomRight,
  65. child: Padding(
  66. padding: EdgeInsets.only(right: 4, bottom: 4),
  67. child: Icon(
  68. Icons.album_outlined,
  69. size: 14,
  70. color: Colors.white, // fixed
  71. ),
  72. ),
  73. );
  74. }
  75. }
  76. class OwnerAvatarOverlayIcon extends StatelessWidget {
  77. final User user;
  78. const OwnerAvatarOverlayIcon(this.user, {Key? key}) : super(key: key);
  79. @override
  80. Widget build(BuildContext context) {
  81. return Align(
  82. alignment: Alignment.topRight,
  83. child: Padding(
  84. padding: const EdgeInsets.only(right: 4, top: 4),
  85. child: UserAvatarWidget(
  86. user,
  87. type: AvatarType.tiny,
  88. thumbnailView: true,
  89. ),
  90. ),
  91. );
  92. }
  93. }
  94. class TrashedFileOverlayText extends StatelessWidget {
  95. final TrashFile file;
  96. const TrashedFileOverlayText(this.file, {Key? key}) : super(key: key);
  97. @override
  98. Widget build(BuildContext context) {
  99. return Container(
  100. decoration: BoxDecoration(
  101. gradient: LinearGradient(
  102. begin: Alignment.bottomCenter,
  103. end: Alignment.topCenter,
  104. colors: [Colors.black.withOpacity(0.33), Colors.transparent],
  105. ),
  106. ),
  107. alignment: Alignment.bottomCenter,
  108. padding: const EdgeInsets.only(bottom: 5),
  109. child: Text(
  110. daysLeft(file.deleteBy),
  111. style: Theme.of(context)
  112. .textTheme
  113. .subtitle2!
  114. .copyWith(color: Colors.white), //same for both themes
  115. ),
  116. );
  117. }
  118. }
  119. // Base variations
  120. /// Icon overlay in the bottom left.
  121. ///
  122. /// This usually indicates ente specific state of a file, e.g. if it is
  123. /// favorited/archived.
  124. class BottomLeftOverlayIcon extends StatelessWidget {
  125. final IconData icon;
  126. /// Overriddable color. Default is a fixed white.
  127. final Color color;
  128. /// Overriddable default size. This is just the initial hint, the actual size
  129. /// is dynamic based on the widget's width (so that we show smaller icons in
  130. /// smaller thumbnails).
  131. final double baseSize;
  132. const BottomLeftOverlayIcon(
  133. this.icon, {
  134. Key? key,
  135. this.baseSize = 24,
  136. this.color = Colors.white, // fixed
  137. }) : super(key: key);
  138. @override
  139. Widget build(BuildContext context) {
  140. return LayoutBuilder(
  141. builder: (context, constraints) {
  142. double inset = 4;
  143. double size = baseSize;
  144. if (constraints.hasBoundedWidth) {
  145. final w = constraints.maxWidth;
  146. if (w > 120) {
  147. size = 24;
  148. } else if (w < 75) {
  149. inset = 3;
  150. size = 16;
  151. }
  152. }
  153. return Container(
  154. decoration: const BoxDecoration(
  155. gradient: LinearGradient(
  156. begin: Alignment.bottomLeft,
  157. end: Alignment.center,
  158. colors: [
  159. Color.fromRGBO(0, 0, 0, 0.14),
  160. Color.fromRGBO(0, 0, 0, 0.05),
  161. Color.fromRGBO(0, 0, 0, 0.0),
  162. ],
  163. stops: [0, 0.6, 1],
  164. ),
  165. ),
  166. child: Align(
  167. alignment: Alignment.bottomLeft,
  168. child: Padding(
  169. padding: EdgeInsets.only(left: inset, bottom: inset),
  170. child: Icon(
  171. icon,
  172. size: size,
  173. color: color,
  174. ),
  175. ),
  176. ),
  177. );
  178. },
  179. );
  180. }
  181. }