subscription_common_widgets.dart 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. import 'package:flutter/material.dart';
  2. import "package:intl/intl.dart";
  3. import 'package:photos/ente_theme_data.dart';
  4. import "package:photos/generated/l10n.dart";
  5. import 'package:photos/models/subscription.dart';
  6. import "package:photos/services/update_service.dart";
  7. import "package:photos/theme/ente_theme.dart";
  8. import "package:photos/ui/components/captioned_text_widget.dart";
  9. import "package:photos/ui/components/menu_item_widget/menu_item_widget.dart";
  10. import 'package:photos/ui/payment/billing_questions_widget.dart';
  11. import 'package:photos/utils/data_util.dart';
  12. class SubscriptionHeaderWidget extends StatefulWidget {
  13. final bool? isOnboarding;
  14. final int? currentUsage;
  15. const SubscriptionHeaderWidget({
  16. Key? key,
  17. this.isOnboarding,
  18. this.currentUsage,
  19. }) : super(key: key);
  20. @override
  21. State<StatefulWidget> createState() {
  22. return _SubscriptionHeaderWidgetState();
  23. }
  24. }
  25. class _SubscriptionHeaderWidgetState extends State<SubscriptionHeaderWidget> {
  26. @override
  27. Widget build(BuildContext context) {
  28. if (widget.isOnboarding!) {
  29. return Padding(
  30. padding: const EdgeInsets.fromLTRB(20, 20, 20, 24),
  31. child: Column(
  32. crossAxisAlignment: CrossAxisAlignment.start,
  33. children: [
  34. Row(
  35. children: [
  36. Text(
  37. S.of(context).selectYourPlan,
  38. style: Theme.of(context).textTheme.headlineMedium,
  39. ),
  40. ],
  41. ),
  42. const SizedBox(height: 10),
  43. Text(
  44. S.of(context).enteSubscriptionPitch,
  45. style: Theme.of(context).textTheme.bodySmall,
  46. ),
  47. const SizedBox(height: 4),
  48. Text(
  49. S.of(context).enteSubscriptionShareWithFamily,
  50. style: Theme.of(context).textTheme.bodySmall,
  51. ),
  52. ],
  53. ),
  54. );
  55. } else {
  56. return SizedBox(
  57. height: 72,
  58. width: double.infinity,
  59. child: Padding(
  60. padding: const EdgeInsets.all(24.0),
  61. child: RichText(
  62. text: TextSpan(
  63. children: [
  64. TextSpan(
  65. text: S.of(context).currentUsageIs,
  66. style: Theme.of(context).textTheme.titleMedium,
  67. ),
  68. TextSpan(
  69. text: formatBytes(widget.currentUsage!),
  70. style: Theme.of(context)
  71. .textTheme
  72. .titleMedium!
  73. .copyWith(fontWeight: FontWeight.bold),
  74. )
  75. ],
  76. ),
  77. ),
  78. ),
  79. );
  80. }
  81. }
  82. }
  83. class ValidityWidget extends StatelessWidget {
  84. final Subscription? currentSubscription;
  85. const ValidityWidget({Key? key, this.currentSubscription}) : super(key: key);
  86. @override
  87. Widget build(BuildContext context) {
  88. if (currentSubscription == null) {
  89. return const SizedBox.shrink();
  90. }
  91. final endDate =
  92. DateFormat.yMMMd(Localizations.localeOf(context).languageCode).format(
  93. DateTime.fromMicrosecondsSinceEpoch(currentSubscription!.expiryTime),
  94. );
  95. var message = S.of(context).renewsOn(endDate);
  96. if (currentSubscription!.productID == freeProductID) {
  97. message = UpdateService.instance.isPlayStoreFlavor()
  98. ? S.of(context).playStoreFreeTrialValidTill(endDate)
  99. : S.of(context).freeTrialValidTill(endDate);
  100. } else if (currentSubscription!.attributes?.isCancelled ?? false) {
  101. message = S.of(context).subWillBeCancelledOn(endDate);
  102. }
  103. return Padding(
  104. padding: const EdgeInsets.only(top: 8),
  105. child: Text(
  106. message,
  107. style: Theme.of(context).textTheme.bodySmall,
  108. textAlign: TextAlign.center,
  109. ),
  110. );
  111. }
  112. }
  113. class SubFaqWidget extends StatelessWidget {
  114. final bool isOnboarding;
  115. const SubFaqWidget({Key? key, this.isOnboarding = false}) : super(key: key);
  116. @override
  117. Widget build(BuildContext context) {
  118. final colorScheme = getEnteColorScheme(context);
  119. return Padding(
  120. padding: EdgeInsets.fromLTRB(16, 40, 16, isOnboarding ? 40 : 4),
  121. child: MenuItemWidget(
  122. captionedTextWidget: CaptionedTextWidget(
  123. title: S.of(context).faqs,
  124. ),
  125. menuItemColor: colorScheme.fillFaint,
  126. trailingWidget: Icon(
  127. Icons.chevron_right_outlined,
  128. color: colorScheme.strokeBase,
  129. ),
  130. singleBorderRadius: 4,
  131. alignCaptionedTextToLeft: true,
  132. onTap: () async {
  133. showModalBottomSheet<void>(
  134. backgroundColor: Theme.of(context).colorScheme.bgColorForQuestions,
  135. barrierColor: Colors.black87,
  136. context: context,
  137. builder: (context) {
  138. return const BillingQuestionsWidget();
  139. },
  140. );
  141. },
  142. ),
  143. );
  144. }
  145. }