Skip to content

Commit 2661ad2

Browse files
authored
feat: improve password error message (#7842)
* chore: update i18n * chore: bump client api version * chore: try to fix the mobile build * chore: enable iOS CI
1 parent 15bfdfb commit 2661ad2

File tree

9 files changed

+272
-175
lines changed

9 files changed

+272
-175
lines changed

.github/workflows/ios_ci.yaml

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -94,26 +94,26 @@ jobs:
9494
cargo make --profile development-ios-arm64-sim appflowy-core-dev-ios
9595
cargo make --profile development-ios-arm64-sim code_generation
9696
97-
- uses: futureware-tech/simulator-action@v3
98-
id: simulator-action
99-
with:
100-
model: "iPhone 15"
101-
shutdown_after_job: false
102-
103-
- name: Run AppFlowy on simulator
104-
working-directory: frontend/appflowy_flutter
105-
run: |
106-
flutter run -d ${{ steps.simulator-action.outputs.udid }} &
107-
pid=$!
108-
sleep 500
109-
kill $pid
110-
continue-on-error: true
111-
112-
# Integration tests
113-
- name: Run integration tests
114-
working-directory: frontend/appflowy_flutter
115-
# The integration tests are flaky and sometimes fail with "Connection timed out":
116-
# Don't block the CI. If the tests fail, the CI will still pass.
117-
# Instead, we're using Code Magic to re-run the tests to check if they pass.
118-
continue-on-error: true
119-
run: flutter test integration_test/runner.dart -d ${{ steps.simulator-action.outputs.udid }}
97+
# - uses: futureware-tech/simulator-action@v3
98+
# id: simulator-action
99+
# with:
100+
# model: "iPhone 15"
101+
# shutdown_after_job: false
102+
103+
# - name: Run AppFlowy on simulator
104+
# working-directory: frontend/appflowy_flutter
105+
# run: |
106+
# flutter run -d ${{ steps.simulator-action.outputs.udid }} &
107+
# pid=$!
108+
# sleep 500
109+
# kill $pid
110+
# continue-on-error: true
111+
112+
# # Integration tests
113+
# - name: Run integration tests
114+
# working-directory: frontend/appflowy_flutter
115+
# # The integration tests are flaky and sometimes fail with "Connection timed out":
116+
# # Don't block the CI. If the tests fail, the CI will still pass.
117+
# # Instead, we're using Code Magic to re-run the tests to check if they pass.
118+
# continue-on-error: true
119+
# run: flutter test integration_test/runner.dart -d ${{ steps.simulator-action.outputs.udid }}

frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/account/account_deletion.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ class _AccountDeletionButtonState extends State<AccountDeletionButton> {
4545
Widget build(BuildContext context) {
4646
final theme = AppFlowyTheme.of(context);
4747
return Row(
48-
crossAxisAlignment: CrossAxisAlignment.start,
4948
children: [
5049
Expanded(
5150
child: Column(

frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/account/password/change_password.dart

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import 'package:appflowy/generated/flowy_svgs.g.dart';
22
import 'package:appflowy/generated/locale_keys.g.dart';
33
import 'package:appflowy/user/application/password/password_bloc.dart';
4+
import 'package:appflowy/workspace/presentation/settings/pages/account/password/error_extensions.dart';
45
import 'package:appflowy/workspace/presentation/settings/pages/account/password/password_suffix_icon.dart';
56
import 'package:appflowy/workspace/presentation/widgets/dialogs.dart';
67
import 'package:appflowy_backend/protobuf/flowy-user/user_profile.pb.dart';
@@ -342,18 +343,25 @@ class _ChangePasswordDialogContentState
342343
message = LocaleKeys
343344
.newSettings_myAccount_password_toast_passwordUpdatedFailed
344345
.tr();
345-
if (error.msg.contains('Incorrect current password')) {
346+
347+
if (AFPasswordErrorExtension.incorrectPasswordPattern
348+
.hasMatch(error.msg)) {
346349
currentPasswordTextFieldKey.currentState?.syncError(
347-
errorText: LocaleKeys
348-
.newSettings_myAccount_password_error_currentPasswordIsIncorrect
349-
.tr(),
350+
errorText: AFPasswordErrorExtension.getErrorMessage(error),
351+
);
352+
} else if (AFPasswordErrorExtension.tooShortPasswordPattern
353+
.hasMatch(error.msg)) {
354+
newPasswordTextFieldKey.currentState?.syncError(
355+
errorText: AFPasswordErrorExtension.getErrorMessage(error),
356+
);
357+
} else if (AFPasswordErrorExtension.tooLongPasswordPattern
358+
.hasMatch(error.msg)) {
359+
newPasswordTextFieldKey.currentState?.syncError(
360+
errorText: AFPasswordErrorExtension.getErrorMessage(error),
350361
);
351-
} else if (error.msg
352-
.contains('Password should be at least 6 characters.')) {
362+
} else {
353363
newPasswordTextFieldKey.currentState?.syncError(
354-
errorText: LocaleKeys
355-
.newSettings_myAccount_password_error_passwordShouldBeAtLeast6Characters
356-
.tr(),
364+
errorText: error.msg,
357365
);
358366
}
359367
},
@@ -367,9 +375,6 @@ class _ChangePasswordDialogContentState
367375
},
368376
(error) {
369377
hasError = true;
370-
message = LocaleKeys
371-
.newSettings_myAccount_password_toast_passwordSetupFailed
372-
.tr();
373378
},
374379
);
375380
}
@@ -379,9 +384,6 @@ class _ChangePasswordDialogContentState
379384
showToastNotification(
380385
message: message,
381386
);
382-
}
383-
384-
if (!hasError) {
385387
Navigator.of(context).pop();
386388
}
387389
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import 'package:appflowy/generated/locale_keys.g.dart';
2+
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
3+
import 'package:easy_localization/easy_localization.dart';
4+
5+
class AFPasswordErrorExtension {
6+
static final RegExp incorrectPasswordPattern =
7+
RegExp('Incorrect current password');
8+
static final RegExp tooShortPasswordPattern =
9+
RegExp(r'Password should be at least (\d+) characters');
10+
static final RegExp tooLongPasswordPattern =
11+
RegExp(r'Password cannot be longer than (\d+) characters');
12+
13+
static String getErrorMessage(FlowyError error) {
14+
final msg = error.msg;
15+
if (incorrectPasswordPattern.hasMatch(msg)) {
16+
return LocaleKeys
17+
.newSettings_myAccount_password_error_currentPasswordIsIncorrect
18+
.tr();
19+
} else if (tooShortPasswordPattern.hasMatch(msg)) {
20+
return LocaleKeys
21+
.newSettings_myAccount_password_error_passwordShouldBeAtLeast6Characters
22+
.tr(
23+
namedArgs: {
24+
'min': tooShortPasswordPattern.firstMatch(msg)?.group(1) ?? '6',
25+
},
26+
);
27+
} else if (tooLongPasswordPattern.hasMatch(msg)) {
28+
return LocaleKeys
29+
.newSettings_myAccount_password_error_passwordCannotBeLongerThan72Characters
30+
.tr(
31+
namedArgs: {
32+
'max': tooLongPasswordPattern.firstMatch(msg)?.group(1) ?? '72',
33+
},
34+
);
35+
}
36+
37+
return msg;
38+
}
39+
}

frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/account/password/setup_password.dart

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import 'package:appflowy/generated/flowy_svgs.g.dart';
22
import 'package:appflowy/generated/locale_keys.g.dart';
33
import 'package:appflowy/user/application/password/password_bloc.dart';
4+
import 'package:appflowy/workspace/presentation/settings/pages/account/password/error_extensions.dart';
45
import 'package:appflowy/workspace/presentation/settings/pages/account/password/password_suffix_icon.dart';
56
import 'package:appflowy/workspace/presentation/widgets/dialogs.dart';
67
import 'package:appflowy_backend/protobuf/flowy-user/user_profile.pb.dart';
@@ -268,7 +269,6 @@ class _SetupPasswordDialogContentState
268269
void _onPasswordStateChanged(BuildContext context, PasswordState state) {
269270
bool hasError = false;
270271
String message = '';
271-
String description = '';
272272

273273
final setPasswordResult = state.setupPasswordResult;
274274

@@ -281,22 +281,31 @@ class _SetupPasswordDialogContentState
281281
},
282282
(error) {
283283
hasError = true;
284-
message = LocaleKeys
285-
.newSettings_myAccount_password_toast_passwordSetupFailed
286-
.tr();
287-
description = error.msg;
284+
if (AFPasswordErrorExtension.tooShortPasswordPattern
285+
.hasMatch(error.msg)) {
286+
passwordTextFieldKey.currentState?.syncError(
287+
errorText: AFPasswordErrorExtension.getErrorMessage(error),
288+
);
289+
} else if (AFPasswordErrorExtension.tooLongPasswordPattern
290+
.hasMatch(error.msg)) {
291+
passwordTextFieldKey.currentState?.syncError(
292+
errorText: AFPasswordErrorExtension.getErrorMessage(error),
293+
);
294+
} else {
295+
passwordTextFieldKey.currentState?.syncError(
296+
errorText: error.msg,
297+
);
298+
}
288299
},
289300
);
290301
}
291302

292303
if (!state.isSubmitting && message.isNotEmpty) {
293-
showToastNotification(
294-
message: message,
295-
description: description,
296-
type: hasError ? ToastificationType.error : ToastificationType.success,
297-
);
298-
299304
if (!hasError) {
305+
showToastNotification(
306+
message: message,
307+
);
308+
300309
Navigator.of(context).pop();
301310
}
302311
}

frontend/resources/translations/en.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2721,7 +2721,8 @@
27212721
"passwordsDoNotMatch": "Passwords do not match",
27222722
"newPasswordIsSameAsCurrent": "New password is same as current password",
27232723
"currentPasswordIsIncorrect": "Current password is incorrect",
2724-
"passwordShouldBeAtLeast6Characters": "Password should be at least 6 characters"
2724+
"passwordShouldBeAtLeast6Characters": "Password should be at least {min} characters",
2725+
"passwordCannotBeLongerThan72Characters": "Password cannot be longer than {max} characters"
27252726
},
27262727
"toast": {
27272728
"passwordUpdatedSuccessfully": "Password updated successfully",
@@ -3371,4 +3372,4 @@
33713372
"rewrite": "Rewrite",
33723373
"insertBelow": "Insert below"
33733374
}
3374-
}
3375+
}

frontend/rust-lib/Cargo.lock

Lines changed: 13 additions & 13 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frontend/rust-lib/Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,9 @@ num_enum = "0.7.3"
109109
# Run the script.add_workspace_members:
110110
# scripts/tool/update_client_api_rev.sh new_rev_id
111111
# ⚠️⚠️⚠️️
112-
client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "c7176311ca375a672bc01bec0baa101986af023f" }
113-
client-api-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "c7176311ca375a672bc01bec0baa101986af023f" }
114-
workspace-template = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "c7176311ca375a672bc01bec0baa101986af023f" }
112+
client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "6ed0f4e" }
113+
client-api-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "6ed0f4e" }
114+
workspace-template = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "6ed0f4e" }
115115

116116
[profile.dev]
117117
opt-level = 0

0 commit comments

Comments
 (0)