Skip to content

Commit ba952c3

Browse files
committed
profile: Display user email
Fixes: #291
1 parent 506a89c commit ba952c3

File tree

2 files changed

+37
-2
lines changed

2 files changed

+37
-2
lines changed

lib/widgets/profile.dart

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@ import 'dart:convert';
33
import 'package:flutter/material.dart';
44
import 'package:flutter_gen/gen_l10n/zulip_localizations.dart';
55

6+
import '../api/model/initial_snapshot.dart';
67
import '../api/model/model.dart';
78
import '../model/content.dart';
89
import '../model/narrow.dart';
10+
import '../model/store.dart';
911
import 'content.dart';
1012
import 'message_list.dart';
1113
import 'page.dart';
@@ -33,6 +35,33 @@ class ProfilePage extends StatelessWidget {
3335
page: ProfilePage(userId: userId));
3436
}
3537

38+
/// The given user's real email address, if known, for displaying in the UI.
39+
///
40+
/// Returns null if self-user isn't able to see [user]'s real email address.
41+
String? _getDisplayEmailFor(User user, {required PerAccountStore store}) {
42+
if (store.account.zulipFeatureLevel >= 163) { // TODO(server-7)
43+
// A non-null value means self-user has access to [user]'s real email,
44+
// while a null value means it doesn't have access to the email.
45+
// Search for "delivery_email" in https://zulip.com/api/register-queue.
46+
return user.deliveryEmail;
47+
} else {
48+
if (user.deliveryEmail != null) {
49+
// A non-null value means self-user has access to [user]'s real email,
50+
// while a null value doesn't necessarily mean it doesn't have access
51+
// to the email, ....
52+
return user.deliveryEmail;
53+
} else if (store.emailAddressVisibility == EmailAddressVisibility.everyone) {
54+
// ... we have to also check for [PerAccountStore.emailAddressVisibility].
55+
// See:
56+
// * https://github.com/zulip/zulip-mobile/pull/5515#discussion_r997731727
57+
// * https://chat.zulip.org/#narrow/stream/378-api-design/topic/email.20address.20visibility/near/1296133
58+
return user.email;
59+
} else {
60+
return null;
61+
}
62+
}
63+
}
64+
3665
@override
3766
Widget build(BuildContext context) {
3867
final zulipLocalizations = ZulipLocalizations.of(context);
@@ -42,6 +71,7 @@ class ProfilePage extends StatelessWidget {
4271
return const _ProfileErrorPage();
4372
}
4473

74+
final displayEmail = _getDisplayEmailFor(user, store: store);
4575
final items = [
4676
Center(
4777
child: Avatar(userId: userId, size: 200, borderRadius: 200 / 8)),
@@ -50,7 +80,10 @@ class ProfilePage extends StatelessWidget {
5080
textAlign: TextAlign.center,
5181
style: _TextStyles.primaryFieldText
5282
.merge(weightVariableTextStyle(context, wght: 700))),
53-
// TODO(#291) render email field
83+
if (displayEmail != null)
84+
Text(displayEmail,
85+
textAlign: TextAlign.center,
86+
style: _TextStyles.primaryFieldText),
5487
Text(roleToLabel(user.role, zulipLocalizations),
5588
textAlign: TextAlign.center,
5689
style: _TextStyles.primaryFieldText),

test/widgets/profile_test.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,14 @@ void main() {
7171

7272
group('ProfilePage', () {
7373
testWidgets('page builds; profile page renders', (WidgetTester tester) async {
74-
final user = eg.user(userId: 1, fullName: 'test user');
74+
final user = eg.user(userId: 1, fullName: 'test user',
75+
deliveryEmail: '[email protected]');
7576

7677
await setupPage(tester, users: [user], pageUserId: user.userId);
7778

7879
check(because: 'find user avatar', find.byType(Avatar).evaluate()).length.equals(1);
7980
check(because: 'find user name', find.text('test user').evaluate()).isNotEmpty();
81+
check(because: 'find user delivery email', find.text('[email protected]').evaluate()).isNotEmpty();
8082
});
8183

8284
testWidgets('page builds; profile page renders with profileData', (WidgetTester tester) async {

0 commit comments

Comments
 (0)