Przeglądaj źródła

resolve conflicts and merge main

ashilkn 1 rok temu
rodzic
commit
b4b4080149

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

@@ -694,6 +694,12 @@ class MessageLookup extends MessageLookupByLibrary {
             MessageLookupByLibrary.simpleMessage("Grant permission"),
         "groupNearbyPhotos":
             MessageLookupByLibrary.simpleMessage("Group nearby photos"),
+        "hearUsExplanation": MessageLookupByLibrary.simpleMessage(
+            "We don\'t track app installs. It\'d help if you told us where you found us!"),
+        "hearUsHint": MessageLookupByLibrary.simpleMessage(
+            "friend, reddit, ad, search, etc."),
+        "hearUsWhereTitle": MessageLookupByLibrary.simpleMessage(
+            "How did you hear about Ente? (optional)"),
         "hidden": MessageLookupByLibrary.simpleMessage("Hidden"),
         "hide": MessageLookupByLibrary.simpleMessage("Hide"),
         "hiding": MessageLookupByLibrary.simpleMessage("Hiding..."),

+ 30 - 0
lib/generated/l10n.dart

@@ -7824,6 +7824,36 @@ class S {
       args: [],
     );
   }
+
+  /// `How did you hear about Ente? (optional)`
+  String get hearUsWhereTitle {
+    return Intl.message(
+      'How did you hear about Ente? (optional)',
+      name: 'hearUsWhereTitle',
+      desc: '',
+      args: [],
+    );
+  }
+
+  /// `friend, reddit, ad, search, etc.`
+  String get hearUsHint {
+    return Intl.message(
+      'friend, reddit, ad, search, etc.',
+      name: 'hearUsHint',
+      desc: '',
+      args: [],
+    );
+  }
+
+  /// `We don't track app installs. It'd help if you told us where you found us!`
+  String get hearUsExplanation {
+    return Intl.message(
+      'We don\'t track app installs. It\'d help if you told us where you found us!',
+      name: 'hearUsExplanation',
+      desc: '',
+      args: [],
+    );
+  }
 }
 
 class AppLocalizationDelegate extends LocalizationsDelegate<S> {

+ 3 - 1
lib/l10n/intl_en.arb

@@ -1114,5 +1114,7 @@
   "addToHiddenAlbum": "Add to hidden album",
   "moveToHiddenAlbum": "Move to hidden album",
   "fileTypes": "File types",
-  "deleteConfirmDialogBody": "This account is linked to other ente apps, if you use any.\\n\\nYour uploaded data, across all ente apps, will be scheduled for deletion, and your account will be permanently deleted."
+  "deleteConfirmDialogBody": "This account is linked to other ente apps, if you use any.\\n\\nYour uploaded data, across all ente apps, will be scheduled for deletion, and your account will be permanently deleted.",
+  "hearUsWhereTitle": "How did you hear about Ente? (optional)",
+  "hearUsExplanation": "We don't track app installs. It'd help if you told us where you found us!"
 }

+ 17 - 4
lib/services/user_service.dart

@@ -52,6 +52,7 @@ import "package:uuid/uuid.dart";
 class UserService {
   static const keyHasEnabledTwoFactor = "has_enabled_two_factor";
   static const keyUserDetails = "user_details";
+  static const kReferralSource = "referral_source";
 
   final SRP6GroupParameters kDefaultSrpGroup = SRP6StandardGroups.rfc5054_4096;
   final _dio = NetworkClient.instance.getDio();
@@ -318,13 +319,17 @@ class UserService {
   }) async {
     final dialog = createProgressDialog(context, S.of(context).pleaseWait);
     await dialog.show();
+    final verifyData = {
+      "email": _config.getEmail(),
+      "ott": ott,
+    };
+    if (!_config.isLoggedIn()) {
+      verifyData["source"] = _getRefSource();
+    }
     try {
       final response = await _dio.post(
         _config.getHttpEndpoint() + "/users/verify-email",
-        data: {
-          "email": _config.getEmail(),
-          "ott": ott,
-        },
+        data: verifyData,
       );
       await dialog.hide();
       if (response.statusCode == 200) {
@@ -392,6 +397,14 @@ class UserService {
     emailValueNotifier.value = email;
   }
 
+  Future<void> setRefSource(String refSource) async {
+    await _preferences.setString(kReferralSource, refSource);
+  }
+
+  String _getRefSource() {
+    return _preferences.getString(kReferralSource) ?? "";
+  }
+
   Future<void> changeEmail(
     BuildContext context,
     String email,

+ 80 - 27
lib/ui/account/email_entry_page.dart

@@ -6,8 +6,10 @@ import 'package:photos/core/configuration.dart';
 import 'package:photos/ente_theme_data.dart';
 import "package:photos/generated/l10n.dart";
 import 'package:photos/services/user_service.dart';
+import "package:photos/theme/ente_theme.dart";
 import 'package:photos/ui/common/dynamic_fab.dart';
 import 'package:photos/ui/common/web_page.dart';
+import "package:photos/utils/toast_util.dart";
 import 'package:step_progress_indicator/step_progress_indicator.dart';
 import "package:styled_text/styled_text.dart";
 
@@ -30,6 +32,7 @@ class _EmailEntryPageState extends State<EmailEntryPage> {
   String? _email;
   String? _password;
   String _cnfPassword = '';
+  String _referralSource = '';
   double _passwordStrength = 0.0;
   bool _emailIsValid = false;
   bool _hasAgreedToTOS = true;
@@ -104,6 +107,7 @@ class _EmailEntryPageState extends State<EmailEntryPage> {
         onPressedFunction: () {
           _config.setVolatilePassword(_passwordController1.text);
           UserService.instance.setEmail(_email!);
+          UserService.instance.setRefSource(_referralSource);
           UserService.instance
               .sendOtt(context, _email!, isCreateAccountScreen: true);
           FocusScope.of(context).unfocus();
@@ -325,6 +329,52 @@ class _EmailEntryPageState extends State<EmailEntryPage> {
                   ),
                 ),
                 const SizedBox(height: 4),
+                Padding(
+                  padding:
+                      const EdgeInsets.symmetric(vertical: 0, horizontal: 20),
+                  child: Text(
+                    S.of(context).hearUsWhereTitle,
+                    style: getEnteTextTheme(context).smallFaint,
+                  ),
+                ),
+                const SizedBox(height: 4),
+                Padding(
+                  padding: const EdgeInsets.fromLTRB(20, 0, 20, 0),
+                  child: TextFormField(
+                    style: Theme.of(context).textTheme.titleMedium,
+                    decoration: InputDecoration(
+                      fillColor: null,
+                      filled: true,
+                      contentPadding: const EdgeInsets.symmetric(
+                        horizontal: 16,
+                        vertical: 14,
+                      ),
+                      border: UnderlineInputBorder(
+                        borderSide: BorderSide.none,
+                        borderRadius: BorderRadius.circular(6),
+                      ),
+                      suffixIcon: InkWell(
+                        onTap: () {
+                          showToast(
+                            context,
+                            S.of(context).hearUsExplanation,
+                            iosLongToastLengthInSec: 4,
+                          );
+                        },
+                        child: Icon(
+                          Icons.info_outline_rounded,
+                          color: getEnteColorScheme(context).fillStrong,
+                        ),
+                      ),
+                    ),
+                    onChanged: (value) {
+                      _referralSource = value.trim();
+                    },
+                    autocorrect: false,
+                    keyboardType: TextInputType.text,
+                    textInputAction: TextInputAction.next,
+                  ),
+                ),
                 const Divider(thickness: 1),
                 const SizedBox(height: 12),
                 _getAgreement(),
@@ -377,31 +427,33 @@ class _EmailEntryPageState extends State<EmailEntryPage> {
                   .copyWith(fontSize: 12),
               tags: {
                 'u-terms': StyledTextActionTag(
-                  (String? text, Map<String?, String?> attrs) => Navigator.of(context).push(
-                      MaterialPageRoute(
-                        builder: (BuildContext context) {
-                          return WebPage(
-                            S.of(context).termsOfServicesTitle,
-                            "https://ente.io/terms",
-                          );
-                        },
-                      ),
+                  (String? text, Map<String?, String?> attrs) =>
+                      Navigator.of(context).push(
+                    MaterialPageRoute(
+                      builder: (BuildContext context) {
+                        return WebPage(
+                          S.of(context).termsOfServicesTitle,
+                          "https://ente.io/terms",
+                        );
+                      },
                     ),
+                  ),
                   style: const TextStyle(
                     decoration: TextDecoration.underline,
                   ),
                 ),
                 'u-policy': StyledTextActionTag(
-                  (String? text, Map<String?, String?> attrs) => Navigator.of(context).push(
-                      MaterialPageRoute(
-                        builder: (BuildContext context) {
-                          return WebPage(
-                            S.of(context).privacyPolicyTitle,
-                            "https://ente.io/privacy",
-                          );
-                        },
-                      ),
+                  (String? text, Map<String?, String?> attrs) =>
+                      Navigator.of(context).push(
+                    MaterialPageRoute(
+                      builder: (BuildContext context) {
+                        return WebPage(
+                          S.of(context).privacyPolicyTitle,
+                          "https://ente.io/privacy",
+                        );
+                      },
                     ),
+                  ),
                   style: const TextStyle(
                     decoration: TextDecoration.underline,
                   ),
@@ -442,16 +494,17 @@ class _EmailEntryPageState extends State<EmailEntryPage> {
                   .copyWith(fontSize: 12),
               tags: {
                 'underline': StyledTextActionTag(
-                  (String? text, Map<String?, String?> attrs) => Navigator.of(context).push(
-                      MaterialPageRoute(
-                        builder: (BuildContext context) {
-                          return WebPage(
-                            S.of(context).encryption,
-                            "https://ente.io/architecture",
-                          );
-                        },
-                      ),
+                  (String? text, Map<String?, String?> attrs) =>
+                      Navigator.of(context).push(
+                    MaterialPageRoute(
+                      builder: (BuildContext context) {
+                        return WebPage(
+                          S.of(context).encryption,
+                          "https://ente.io/architecture",
+                        );
+                      },
                     ),
+                  ),
                   style: const TextStyle(
                     decoration: TextDecoration.underline,
                   ),

+ 5 - 1
lib/utils/toast_util.dart

@@ -9,6 +9,7 @@ Future showToast(
   BuildContext context,
   String message, {
   toastLength = Toast.LENGTH_LONG,
+  int iosLongToastLengthInSec = 2,
 }) async {
   if (Platform.isAndroid) {
     await Fluttertoast.cancel();
@@ -30,7 +31,10 @@ Future showToast(
       ..loadingStyle = EasyLoadingStyle.custom;
     return EasyLoading.showToast(
       message,
-      duration: Duration(seconds: (toastLength == Toast.LENGTH_LONG ? 2 : 1)),
+      duration: Duration(
+        seconds:
+            (toastLength == Toast.LENGTH_LONG ? iosLongToastLengthInSec : 1),
+      ),
       toastPosition: EasyLoadingToastPosition.bottom,
       dismissOnTap: false,
     );

+ 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.102+502
+version: 0.7.103+503
 
 environment:
   sdk: ">=3.0.0 <4.0.0"