dialog_widget.dart 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. import 'dart:math';
  2. import 'package:flutter/material.dart';
  3. import 'package:photos/core/constants.dart';
  4. import 'package:photos/theme/colors.dart';
  5. import 'package:photos/theme/effects.dart';
  6. import 'package:photos/theme/ente_theme.dart';
  7. import 'package:photos/ui/components/button_widget.dart';
  8. import 'package:photos/utils/separators_util.dart';
  9. ///Will return null if dismissed by tapping outside
  10. Future<ButtonAction?> showDialogWidget({
  11. required BuildContext context,
  12. required String title,
  13. String? body,
  14. required List<ButtonWidget> buttons,
  15. IconData? icon,
  16. bool isDismissible = true,
  17. }) {
  18. return showDialog(
  19. barrierDismissible: isDismissible,
  20. barrierColor: backdropFaintDark,
  21. context: context,
  22. builder: (context) {
  23. final widthOfScreen = MediaQuery.of(context).size.width;
  24. final isMobileSmall = widthOfScreen <= mobileSmallThreshold;
  25. return Padding(
  26. padding: EdgeInsets.symmetric(horizontal: isMobileSmall ? 8 : 0),
  27. child: Dialog(
  28. insetPadding: EdgeInsets.zero,
  29. child: DialogWidget(
  30. title: title,
  31. body: body,
  32. buttons: buttons,
  33. icon: icon,
  34. ),
  35. ),
  36. );
  37. },
  38. );
  39. }
  40. class DialogWidget extends StatelessWidget {
  41. final String title;
  42. final String? body;
  43. final List<ButtonWidget> buttons;
  44. final IconData? icon;
  45. const DialogWidget({
  46. required this.title,
  47. this.body,
  48. required this.buttons,
  49. this.icon,
  50. super.key,
  51. });
  52. @override
  53. Widget build(BuildContext context) {
  54. final widthOfScreen = MediaQuery.of(context).size.width;
  55. final isMobileSmall = widthOfScreen <= mobileSmallThreshold;
  56. final colorScheme = getEnteColorScheme(context);
  57. return Container(
  58. width: min(widthOfScreen, 320),
  59. padding: isMobileSmall
  60. ? const EdgeInsets.all(0)
  61. : const EdgeInsets.fromLTRB(6, 8, 6, 6),
  62. decoration: BoxDecoration(
  63. color: colorScheme.backgroundElevated,
  64. boxShadow: shadowFloatLight,
  65. borderRadius: const BorderRadius.all(Radius.circular(8)),
  66. ),
  67. child: Padding(
  68. padding: const EdgeInsets.all(16),
  69. child: Column(
  70. mainAxisSize: MainAxisSize.min,
  71. children: [
  72. ContentContainer(
  73. title: title,
  74. body: body,
  75. icon: icon,
  76. ),
  77. const SizedBox(height: 36),
  78. Actions(buttons),
  79. ],
  80. ),
  81. ),
  82. );
  83. }
  84. }
  85. class ContentContainer extends StatelessWidget {
  86. final String title;
  87. final String? body;
  88. final IconData? icon;
  89. const ContentContainer({
  90. required this.title,
  91. this.body,
  92. this.icon,
  93. super.key,
  94. });
  95. @override
  96. Widget build(BuildContext context) {
  97. final textTheme = getEnteTextTheme(context);
  98. final colorScheme = getEnteColorScheme(context);
  99. return Column(
  100. mainAxisSize: MainAxisSize.min,
  101. crossAxisAlignment: CrossAxisAlignment.stretch,
  102. children: [
  103. icon == null
  104. ? const SizedBox.shrink()
  105. : Row(
  106. children: [
  107. Icon(
  108. icon,
  109. size: 32,
  110. ),
  111. ],
  112. ),
  113. icon == null ? const SizedBox.shrink() : const SizedBox(height: 19),
  114. Text(title, style: textTheme.largeBold),
  115. body != null ? const SizedBox(height: 19) : const SizedBox.shrink(),
  116. body != null
  117. ? Text(
  118. body!,
  119. style: textTheme.body.copyWith(color: colorScheme.textMuted),
  120. )
  121. : const SizedBox.shrink(),
  122. ],
  123. );
  124. }
  125. }
  126. class Actions extends StatelessWidget {
  127. final List<ButtonWidget> buttons;
  128. const Actions(this.buttons, {super.key});
  129. @override
  130. Widget build(BuildContext context) {
  131. return Column(
  132. children: addSeparators(
  133. buttons,
  134. const SizedBox(
  135. // In figma this white space is of height 8pts. But the Button
  136. // component has 1pts of invisible border by default in code. So two
  137. // 1pts borders will visually make the whitespace 8pts.
  138. // Height of button component in figma = 48, in code = 50 (2pts for
  139. // top + bottom border)
  140. height: 6,
  141. ),
  142. ),
  143. );
  144. }
  145. }