info_item_widget.dart 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. import "package:flutter/material.dart";
  2. import "package:photos/theme/ente_theme.dart";
  3. import "package:photos/ui/common/loading_widget.dart";
  4. import 'package:photos/ui/components/buttons/icon_button_widget.dart';
  5. ///https://www.figma.com/file/SYtMyLBs5SAOkTbfMMzhqt/ente-Visual-Design?node-id=8113-59605&t=OMX5f5KdDJYWSQQN-4
  6. class InfoItemWidget extends StatelessWidget {
  7. final IconData leadingIcon;
  8. final VoidCallback? editOnTap;
  9. final String? title;
  10. final Widget? endSection;
  11. final Future<List<Widget>> subtitleSection;
  12. final bool hasChipButtons;
  13. final VoidCallback? onTap;
  14. const InfoItemWidget({
  15. required this.leadingIcon,
  16. this.editOnTap,
  17. this.title,
  18. this.endSection,
  19. required this.subtitleSection,
  20. this.hasChipButtons = false,
  21. this.onTap,
  22. super.key,
  23. });
  24. @override
  25. Widget build(BuildContext context) {
  26. final children = <Widget>[];
  27. if (title != null) {
  28. children.addAll([
  29. Text(
  30. title!,
  31. style: hasChipButtons
  32. ? getEnteTextTheme(context).miniMuted
  33. : getEnteTextTheme(context).small,
  34. ),
  35. SizedBox(height: hasChipButtons ? 8 : 4),
  36. ]);
  37. }
  38. children.addAll([
  39. Flexible(
  40. child: FutureBuilder(
  41. future: subtitleSection,
  42. builder: (context, snapshot) {
  43. Widget child;
  44. if (snapshot.hasData) {
  45. final subtitle = snapshot.data as List<Widget>;
  46. if (subtitle.isNotEmpty) {
  47. child = Wrap(
  48. runSpacing: 8,
  49. spacing: 8,
  50. children: subtitle,
  51. );
  52. } else {
  53. child = const SizedBox.shrink();
  54. }
  55. } else {
  56. child = EnteLoadingWidget(
  57. padding: 3,
  58. size: 11,
  59. color: getEnteColorScheme(context).strokeMuted,
  60. alignment: Alignment.centerLeft,
  61. );
  62. }
  63. return AnimatedSwitcher(
  64. duration: const Duration(milliseconds: 200),
  65. switchInCurve: Curves.easeInOutExpo,
  66. child: child,
  67. );
  68. },
  69. ),
  70. ),
  71. ]);
  72. endSection != null ? children.add(endSection!) : null;
  73. return Row(
  74. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  75. crossAxisAlignment: CrossAxisAlignment.start,
  76. children: [
  77. Flexible(
  78. child: Row(
  79. crossAxisAlignment: CrossAxisAlignment.start,
  80. children: [
  81. IconButtonWidget(
  82. icon: leadingIcon,
  83. iconButtonType: IconButtonType.secondary,
  84. ),
  85. Flexible(
  86. child: Padding(
  87. padding: const EdgeInsets.fromLTRB(12, 3.5, 16, 3.5),
  88. child: GestureDetector(
  89. behavior: HitTestBehavior.translucent,
  90. onTap: onTap,
  91. child: SizedBox(
  92. width: double.infinity,
  93. child: Column(
  94. mainAxisSize: MainAxisSize.min,
  95. crossAxisAlignment: CrossAxisAlignment.start,
  96. children: children,
  97. ),
  98. ),
  99. ),
  100. ),
  101. ),
  102. ],
  103. ),
  104. ),
  105. editOnTap != null
  106. ? IconButtonWidget(
  107. icon: Icons.edit,
  108. iconButtonType: IconButtonType.secondary,
  109. onTap: editOnTap,
  110. )
  111. : const SizedBox.shrink(),
  112. ],
  113. );
  114. }
  115. }