info_item_widget.dart 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  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 Future<List<Widget>> subtitleSection;
  11. final bool hasChipButtons;
  12. final VoidCallback? onTap;
  13. const InfoItemWidget({
  14. required this.leadingIcon,
  15. this.editOnTap,
  16. this.title,
  17. required this.subtitleSection,
  18. this.hasChipButtons = false,
  19. this.onTap,
  20. super.key,
  21. });
  22. @override
  23. Widget build(BuildContext context) {
  24. final children = <Widget>[];
  25. if (title != null) {
  26. children.addAll([
  27. Text(
  28. title!,
  29. style: hasChipButtons
  30. ? getEnteTextTheme(context).smallMuted
  31. : getEnteTextTheme(context).body,
  32. ),
  33. SizedBox(height: hasChipButtons ? 8 : 4),
  34. ]);
  35. }
  36. children.addAll([
  37. Flexible(
  38. child: FutureBuilder(
  39. future: subtitleSection,
  40. builder: (context, snapshot) {
  41. Widget child;
  42. if (snapshot.hasData) {
  43. final subtitle = snapshot.data as List<Widget>;
  44. if (subtitle.isNotEmpty) {
  45. child = Wrap(
  46. runSpacing: 8,
  47. spacing: 8,
  48. children: subtitle,
  49. );
  50. } else {
  51. child = const SizedBox.shrink();
  52. }
  53. } else {
  54. child = EnteLoadingWidget(
  55. padding: 3,
  56. size: 11,
  57. color: getEnteColorScheme(context).strokeMuted,
  58. alignment: Alignment.centerLeft,
  59. );
  60. }
  61. return AnimatedSwitcher(
  62. duration: const Duration(milliseconds: 200),
  63. switchInCurve: Curves.easeInOutExpo,
  64. child: child,
  65. );
  66. },
  67. ),
  68. ),
  69. ]);
  70. return Row(
  71. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  72. crossAxisAlignment: CrossAxisAlignment.start,
  73. children: [
  74. Flexible(
  75. child: Row(
  76. crossAxisAlignment: CrossAxisAlignment.start,
  77. children: [
  78. IconButtonWidget(
  79. icon: leadingIcon,
  80. iconButtonType: IconButtonType.secondary,
  81. ),
  82. Flexible(
  83. child: Padding(
  84. padding: const EdgeInsets.fromLTRB(12, 3.5, 16, 3.5),
  85. child: GestureDetector(
  86. behavior: HitTestBehavior.translucent,
  87. onTap: onTap,
  88. child: SizedBox(
  89. width: double.infinity,
  90. child: Column(
  91. mainAxisSize: MainAxisSize.min,
  92. crossAxisAlignment: CrossAxisAlignment.start,
  93. children: children,
  94. ),
  95. ),
  96. ),
  97. ),
  98. ),
  99. ],
  100. ),
  101. ),
  102. editOnTap != null
  103. ? IconButtonWidget(
  104. icon: Icons.edit,
  105. iconButtonType: IconButtonType.secondary,
  106. onTap: editOnTap,
  107. )
  108. : const SizedBox.shrink(),
  109. ],
  110. );
  111. }
  112. }