Quellcode durchsuchen

resolve conflicts and merge main

ashilkn vor 1 Jahr
Ursprung
Commit
7e15691c30

+ 4 - 0
lib/generated/intl/messages_en.dart

@@ -347,6 +347,8 @@ class MessageLookup extends MessageLookupByLibrary {
         "backupSettings":
             MessageLookupByLibrary.simpleMessage("Backup settings"),
         "backupVideos": MessageLookupByLibrary.simpleMessage("Backup videos"),
+        "blackFridaySale":
+            MessageLookupByLibrary.simpleMessage("Black Friday Sale"),
         "blog": MessageLookupByLibrary.simpleMessage("Blog"),
         "cachedData": MessageLookupByLibrary.simpleMessage("Cached data"),
         "calculating": MessageLookupByLibrary.simpleMessage("Calculating..."),
@@ -1338,6 +1340,8 @@ class MessageLookup extends MessageLookupByLibrary {
         "upgrade": MessageLookupByLibrary.simpleMessage("Upgrade"),
         "uploadingFilesToAlbum":
             MessageLookupByLibrary.simpleMessage("Uploading files to album..."),
+        "upto50OffUntil4thDec": MessageLookupByLibrary.simpleMessage(
+            "Upto 50% off, until 4th Dec."),
         "usableReferralStorageInfo": MessageLookupByLibrary.simpleMessage(
             "Usable storage is limited by your current plan. Excess claimed storage will automatically become usable when you upgrade your plan."),
         "usePublicLinksForPeopleNotOnEnte":

+ 20 - 0
lib/generated/l10n.dart

@@ -7895,6 +7895,16 @@ class S {
     );
   }
 
+  /// `Black Friday Sale`
+  String get blackFridaySale {
+    return Intl.message(
+      'Black Friday Sale',
+      name: 'blackFridaySale',
+      desc: '',
+      args: [],
+    );
+  }
+
   /// `Modify your query, or try searching for`
   String get modifyYourQueryOrTrySearchingFor {
     return Intl.message(
@@ -7904,6 +7914,16 @@ class S {
       args: [],
     );
   }
+
+  /// `Upto 50% off, until 4th Dec.`
+  String get upto50OffUntil4thDec {
+    return Intl.message(
+      'Upto 50% off, until 4th Dec.',
+      name: 'upto50OffUntil4thDec',
+      desc: '',
+      args: [],
+    );
+  }
 }
 
 class AppLocalizationDelegate extends LocalizationsDelegate<S> {

+ 4 - 2
lib/l10n/intl_en.arb

@@ -1122,5 +1122,7 @@
   "addOns": "Add-ons",
   "addOnPageSubtitle": "Details of add-ons",
   "yourMap": "Your map",
-  "modifyYourQueryOrTrySearchingFor": "Modify your query, or try searching for"
-}
+  "modifyYourQueryOrTrySearchingFor": "Modify your query, or try searching for",
+  "blackFridaySale": "Black Friday Sale",
+  "upto50OffUntil4thDec": "Upto 50% off, until 4th Dec."
+}

+ 4 - 0
lib/models/user_details.dart

@@ -33,6 +33,10 @@ class UserDetails {
     return familyData?.members?.isNotEmpty ?? false;
   }
 
+  bool hasPaidAddon() {
+    return bonusData?.getAddOnBonuses().isNotEmpty ?? false;
+  }
+
   bool isFamilyAdmin() {
     assert(isPartOfFamily(), "verify user is part of family before calling");
     final FamilyMember currentUserMember = familyData!.members!

+ 2 - 1
lib/services/billing_service.dart

@@ -166,7 +166,8 @@ class BillingService {
     BuildContext context,
     UserDetails userDetails,
   ) async {
-    if (userDetails.subscription.productID == freeProductID) {
+    if (userDetails.subscription.productID == freeProductID &&
+        !userDetails.hasPaidAddon()) {
       await showErrorDialog(
         context,
         S.of(context).familyPlans,

+ 31 - 5
lib/ui/components/notification_widget.dart

@@ -1,4 +1,5 @@
 import 'package:flutter/material.dart';
+import "package:flutter_animate/flutter_animate.dart";
 import "package:photos/ente_theme_data.dart";
 import 'package:photos/theme/colors.dart';
 import "package:photos/theme/ente_theme.dart";
@@ -20,6 +21,7 @@ class NotificationWidget extends StatelessWidget {
   final String? subText;
   final GestureTapCallback onTap;
   final NotificationType type;
+  final bool isBlackFriday;
 
   const NotificationWidget({
     Key? key,
@@ -27,6 +29,7 @@ class NotificationWidget extends StatelessWidget {
     required this.actionIcon,
     required this.text,
     required this.onTap,
+    this.isBlackFriday = false,
     this.subText,
     this.type = NotificationType.warning,
   }) : super(key: key);
@@ -89,11 +92,34 @@ class NotificationWidget extends StatelessWidget {
             child: Row(
               mainAxisAlignment: MainAxisAlignment.spaceBetween,
               children: [
-                Icon(
-                  startIcon,
-                  size: 36,
-                  color: strokeColorScheme.strokeBase,
-                ),
+                isBlackFriday
+                    ? Icon(
+                        startIcon,
+                        size: 36,
+                        color: strokeColorScheme.strokeBase,
+                      )
+                        .animate(
+                          onPlay: (controller) =>
+                              controller.repeat(reverse: true),
+                          delay: 2000.ms,
+                        )
+                        .shake(
+                          duration: 500.ms,
+                          hz: 6,
+                          delay: 1600.ms,
+                        )
+                        .scale(
+                          duration: 500.ms,
+                          begin: const Offset(0.9, 0.9),
+                          end: const Offset(1.1, 1.1),
+                          delay: 1600.ms,
+                          // curve: Curves.easeInOut,
+                        )
+                    : Icon(
+                        startIcon,
+                        size: 36,
+                        color: strokeColorScheme.strokeBase,
+                      ),
                 const SizedBox(width: 12),
                 Expanded(
                   child: Column(

+ 6 - 4
lib/ui/payment/stripe_subscription_page.dart

@@ -211,10 +211,12 @@ class _StripeSubscriptionPageState extends State<StripeSubscriptionPage> {
     widgets.add(_showSubscriptionToggle());
 
     if (_hasActiveSubscription) {
-      widgets.add(ValidityWidget(
-        currentSubscription: _currentSubscription,
-        bonusData: _userDetails.bonusData,
-      ));
+      widgets.add(
+        ValidityWidget(
+          currentSubscription: _currentSubscription,
+          bonusData: _userDetails.bonusData,
+        ),
+      );
     }
 
     if (_currentSubscription!.productID == freeProductID) {

+ 50 - 12
lib/ui/settings_page.dart

@@ -9,6 +9,7 @@ import 'package:photos/events/opened_settings_event.dart';
 import "package:photos/generated/l10n.dart";
 import 'package:photos/services/feature_flag_service.dart';
 import "package:photos/services/storage_bonus_service.dart";
+import "package:photos/services/user_service.dart";
 import 'package:photos/theme/colors.dart';
 import 'package:photos/theme/ente_theme.dart';
 import "package:photos/ui/components/notification_widget.dart";
@@ -28,6 +29,7 @@ import 'package:photos/ui/settings/support_section_widget.dart';
 import 'package:photos/ui/settings/theme_switch_widget.dart';
 import "package:photos/ui/sharing/verify_identity_dialog.dart";
 import "package:photos/utils/navigation_util.dart";
+import "package:url_launcher/url_launcher_string.dart";
 
 class SettingsPage extends StatelessWidget {
   final ValueNotifier<String?> emailNotifier;
@@ -84,23 +86,42 @@ class SettingsPage extends StatelessWidget {
     const sectionSpacing = SizedBox(height: 8);
     contents.add(const SizedBox(height: 8));
     if (hasLoggedIn) {
+      final shouldShowBFBanner = shouldShowBfBanner();
+      final showStorageBonusBanner =
+          StorageBonusService.instance.shouldShowStorageBonus();
       contents.addAll([
         const StorageCardWidget(),
-        StorageBonusService.instance.shouldShowStorageBonus()
+        (shouldShowBFBanner || showStorageBonusBanner)
             ? RepaintBoundary(
                 child: Padding(
                   padding: const EdgeInsets.symmetric(vertical: 8.0),
-                  child: NotificationWidget(
-                    startIcon: Icons.auto_awesome,
-                    actionIcon: Icons.arrow_forward_outlined,
-                    text: S.of(context).doubleYourStorage,
-                    subText: S.of(context).referFriendsAnd2xYourPlan,
-                    type: NotificationType.goldenBanner,
-                    onTap: () async {
-                      StorageBonusService.instance.markStorageBonusAsDone();
-                      routeToPage(context, const ReferralScreen());
-                    },
-                  ),
+                  child: shouldShowBFBanner
+                      ? NotificationWidget(
+                          isBlackFriday: true,
+                          startIcon: Icons.celebration,
+                          actionIcon: Icons.arrow_forward_outlined,
+                          text: S.of(context).blackFridaySale,
+                          subText: S.of(context).upto50OffUntil4thDec,
+                          type: NotificationType.goldenBanner,
+                          onTap: () async {
+                            launchUrlString(
+                              "https://ente.io/blackfriday",
+                              mode: LaunchMode.platformDefault,
+                            );
+                          },
+                        )
+                      : NotificationWidget(
+                          startIcon: Icons.auto_awesome,
+                          actionIcon: Icons.arrow_forward_outlined,
+                          text: S.of(context).doubleYourStorage,
+                          subText: S.of(context).referFriendsAnd2xYourPlan,
+                          type: NotificationType.goldenBanner,
+                          onTap: () async {
+                            StorageBonusService.instance
+                                .markStorageBonusAsDone();
+                            routeToPage(context, const ReferralScreen());
+                          },
+                        ),
                 ).animate(onPlay: (controller) => controller.repeat()).shimmer(
                       duration: 1000.ms,
                       delay: 3200.ms,
@@ -167,6 +188,23 @@ class SettingsPage extends StatelessWidget {
     );
   }
 
+  bool shouldShowBfBanner() {
+    if (!Platform.isAndroid && !kDebugMode) {
+      return false;
+    }
+    // if date is after 5th of December 2023, 00:00:00, hide banner
+    if (DateTime.now().isAfter(DateTime(2023, 12, 5))) {
+      return false;
+    }
+    // if coupon is already applied, can hide the banner
+    return (UserService.instance
+            .getCachedUserDetails()
+            ?.bonusData
+            ?.getAddOnBonuses()
+            .isEmpty ??
+        true);
+  }
+
   Future<void> _showVerifyIdentityDialog(BuildContext context) async {
     await showDialog(
       context: context,

+ 1 - 1
pubspec.yaml

@@ -12,7 +12,7 @@ description: ente photos application
 # Read more about iOS versioning at
 # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
 
-version: 0.7.108+508
+version: 0.7.116+516
 
 environment:
   sdk: ">=3.0.0 <4.0.0"