title_bar_widget.dart 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. import 'package:flutter/material.dart';
  2. import 'package:photos/theme/ente_theme.dart';
  3. import 'package:photos/ui/components/icon_button_widget.dart';
  4. class TitleBarWidget extends StatelessWidget {
  5. final String? title;
  6. final String? caption;
  7. final Widget? flexibleSpaceTitle;
  8. final String? flexibleSpaceCaption;
  9. final List<Widget>? actionIcons;
  10. final bool isTitleH2WithoutLeading;
  11. final bool isFlexibleSpaceDisabled;
  12. const TitleBarWidget({
  13. this.title,
  14. this.caption,
  15. this.flexibleSpaceTitle,
  16. this.flexibleSpaceCaption,
  17. this.actionIcons,
  18. this.isTitleH2WithoutLeading = false,
  19. this.isFlexibleSpaceDisabled = false,
  20. super.key,
  21. });
  22. @override
  23. Widget build(BuildContext context) {
  24. const toolbarHeight = 48.0;
  25. final textTheme = getEnteTextTheme(context);
  26. final colorTheme = getEnteColorScheme(context);
  27. return SliverAppBar(
  28. toolbarHeight: toolbarHeight,
  29. leadingWidth: 48,
  30. automaticallyImplyLeading: false,
  31. pinned: true,
  32. expandedHeight: 102,
  33. centerTitle: false,
  34. titleSpacing: 0,
  35. title: Padding(
  36. padding: EdgeInsets.only(left: isTitleH2WithoutLeading ? 16 : 0),
  37. child: Column(
  38. crossAxisAlignment: CrossAxisAlignment.start,
  39. mainAxisAlignment: MainAxisAlignment.start,
  40. children: [
  41. title == null
  42. ? const SizedBox.shrink()
  43. : Text(
  44. title!,
  45. style: isTitleH2WithoutLeading
  46. ? textTheme.h2Bold
  47. : textTheme.largeBold,
  48. ),
  49. caption == null || isTitleH2WithoutLeading
  50. ? const SizedBox.shrink()
  51. : Text(
  52. caption!,
  53. style: textTheme.mini.copyWith(color: colorTheme.textMuted),
  54. )
  55. ],
  56. ),
  57. ),
  58. actions: [
  59. Padding(
  60. padding: const EdgeInsets.symmetric(horizontal: 4),
  61. child: Row(
  62. children: _actionsWithPaddingInBetween(),
  63. ),
  64. ),
  65. ],
  66. leading: isTitleH2WithoutLeading
  67. ? null
  68. : IconButtonWidget(
  69. icon: Icons.arrow_back_outlined,
  70. isPrimary: true,
  71. onTap: () {
  72. Navigator.pop(context);
  73. },
  74. ),
  75. flexibleSpace: isFlexibleSpaceDisabled
  76. ? null
  77. : FlexibleSpaceBar(
  78. background: SafeArea(
  79. child: Column(
  80. crossAxisAlignment: CrossAxisAlignment.start,
  81. mainAxisSize: MainAxisSize.min,
  82. children: <Widget>[
  83. const SizedBox(height: toolbarHeight),
  84. Padding(
  85. padding: const EdgeInsets.symmetric(
  86. vertical: 4,
  87. horizontal: 16,
  88. ),
  89. child: Column(
  90. crossAxisAlignment: CrossAxisAlignment.start,
  91. children: [
  92. flexibleSpaceTitle == null
  93. ? const SizedBox.shrink()
  94. : flexibleSpaceTitle!,
  95. flexibleSpaceCaption == null
  96. ? const SizedBox.shrink()
  97. : Text(
  98. flexibleSpaceCaption!,
  99. style: textTheme.small.copyWith(
  100. color: colorTheme.textMuted,
  101. ),
  102. overflow: TextOverflow.ellipsis,
  103. maxLines: 1,
  104. )
  105. ],
  106. ),
  107. ),
  108. ],
  109. ),
  110. ),
  111. ),
  112. );
  113. }
  114. _actionsWithPaddingInBetween() {
  115. if (actionIcons == null) {
  116. return <Widget>[const SizedBox.shrink()];
  117. }
  118. final actions = <Widget>[];
  119. bool addWhiteSpace = false;
  120. final length = actionIcons!.length;
  121. int index = 0;
  122. if (length == 0) {
  123. return <Widget>[const SizedBox.shrink()];
  124. }
  125. if (length == 1) {
  126. return actionIcons;
  127. }
  128. while (index < length) {
  129. if (!addWhiteSpace) {
  130. actions.add(actionIcons![index]);
  131. index++;
  132. addWhiteSpace = true;
  133. } else {
  134. actions.add(const SizedBox(width: 4));
  135. addWhiteSpace = false;
  136. }
  137. }
  138. return actions;
  139. }
  140. }