Skip to content

Commit 952c45d

Browse files
committed
login: Display message when account already logged in
This provides some user feedback since the previous behavior looked as if nothing happened. Fixes: #108
1 parent f47f734 commit 952c45d

File tree

3 files changed

+60
-10
lines changed

3 files changed

+60
-10
lines changed

assets/l10n/app_en.arb

+12
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,18 @@
6363
"@actionSheetOptionUnstarMessage": {
6464
"description": "Label for unstar button on action sheet."
6565
},
66+
"errorAccountLoggedInTitle": "Account already logged in",
67+
"@errorAccountLoggedInTitle": {
68+
"description": "Error title on attempting to log into an account that's already logged in."
69+
},
70+
"errorAccountLoggedIn": "The account {email} at {server} is already in your list of accounts.",
71+
"@errorAccountLoggedIn": {
72+
"description": "Error message on attempting to log into an account that's already logged in.",
73+
"placeholders": {
74+
"email": {"type": "String", "example": "[email protected]"},
75+
"server": {"type": "String", "example": "https://example.com"}
76+
}
77+
},
6678
"errorCouldNotFetchMessageSource": "Could not fetch message source",
6779
"@errorCouldNotFetchMessageSource": {
6880
"description": "Error message when the source of a message could not be fetched."

lib/widgets/login.dart

+25-10
Original file line numberDiff line numberDiff line change
@@ -258,16 +258,31 @@ class _PasswordLoginPageState extends State<PasswordLoginPage> {
258258
required int userId,
259259
}) async {
260260
final globalStore = GlobalStoreWidget.of(context);
261-
// TODO(#108): give feedback to user on SQL exception, like dupe realm+user
262-
final accountId = await globalStore.insertAccount(AccountsCompanion.insert(
263-
realmUrl: widget.serverSettings.realmUrl,
264-
email: email,
265-
apiKey: apiKey,
266-
userId: userId,
267-
zulipFeatureLevel: widget.serverSettings.zulipFeatureLevel,
268-
zulipVersion: widget.serverSettings.zulipVersion,
269-
zulipMergeBase: Value(widget.serverSettings.zulipMergeBase),
270-
));
261+
final realmUrl = widget.serverSettings.realmUrl;
262+
final int accountId;
263+
try {
264+
accountId = await globalStore.insertAccount(AccountsCompanion.insert(
265+
realmUrl: realmUrl,
266+
email: email,
267+
apiKey: apiKey,
268+
userId: userId,
269+
zulipFeatureLevel: widget.serverSettings.zulipFeatureLevel,
270+
zulipVersion: widget.serverSettings.zulipVersion,
271+
zulipMergeBase: Value(widget.serverSettings.zulipMergeBase),
272+
));
273+
// TODO give feedback to user on other SQL exceptions
274+
} on AccountAlreadyExistsException {
275+
if (!mounted) {
276+
return;
277+
}
278+
final zulipLocalizations = ZulipLocalizations.of(context);
279+
showErrorDialog(
280+
context: context,
281+
title: zulipLocalizations.errorAccountLoggedInTitle,
282+
message: zulipLocalizations.errorAccountLoggedIn(
283+
email, realmUrl.toString()));
284+
return;
285+
}
271286

272287
if (!mounted) {
273288
return;

test/widgets/login_test.dart

+23
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import 'package:flutter_test/flutter_test.dart';
55
import 'package:http/http.dart' as http;
66
import 'package:zulip/api/route/account.dart';
77
import 'package:zulip/api/route/realm.dart';
8+
import 'package:zulip/model/localizations.dart';
89
import 'package:zulip/widgets/login.dart';
910
import 'package:zulip/widgets/store.dart';
1011

@@ -113,6 +114,28 @@ void main() {
113114
id: testBinding.globalStore.accounts.single.id));
114115
});
115116

117+
testWidgets('account already exists', (tester) async {
118+
final serverSettings = eg.serverSettings();
119+
await prepare(tester, serverSettings);
120+
check(testBinding.globalStore.accounts).isEmpty();
121+
testBinding.globalStore.add(eg.selfAccount, eg.initialSnapshot());
122+
123+
await tester.enterText(findUsernameInput, eg.selfAccount.email);
124+
await tester.enterText(findPasswordInput, 'p455w0rd');
125+
connection.prepare(json: FetchApiKeyResult(
126+
apiKey: eg.selfAccount.apiKey,
127+
email: eg.selfAccount.email,
128+
userId: eg.selfAccount.userId,
129+
).toJson());
130+
await tester.tap(findSubmitButton);
131+
await tester.pumpAndSettle();
132+
133+
final zulipLocalizations = GlobalLocalizations.zulipLocalizations;
134+
final findAlertDialogWithExistsMessage = find.widgetWithText(
135+
AlertDialog, zulipLocalizations.errorAccountLoggedInTitle);
136+
check(findAlertDialogWithExistsMessage.evaluate()).isNotEmpty();
137+
});
138+
116139
// TODO test validators on the TextFormField widgets
117140
// TODO test navigation, i.e. the call to pushAndRemoveUntil
118141
// TODO test _getUserId case

0 commit comments

Comments
 (0)