Skip to content

Commit 3ec3d48

Browse files
refactor: replace contact word for user profile
1 parent 8c5ddb2 commit 3ec3d48

File tree

55 files changed

+557
-1141
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+557
-1141
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Added
1111
### Changed
12+
- Renamed contact to user profile everywhere [#710](https://github.com/parres-hq/whitenoise_flutter/pull/710)
1213
### Deprecated
1314
### Removed
1415
- Removes metadata cache provider [#654](https://github.com/parres-hq/whitenoise_flutter/pull/654)

lib/config/providers/group_messages_provider.dart

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import 'package:flutter_riverpod/flutter_riverpod.dart';
22
import 'package:whitenoise/config/providers/active_pubkey_provider.dart';
3-
import 'package:whitenoise/config/providers/user_profile_data_provider.dart';
4-
import 'package:whitenoise/domain/models/contact_model.dart';
3+
import 'package:whitenoise/config/providers/user_profile_provider.dart';
54
import 'package:whitenoise/domain/models/message_model.dart';
65
import 'package:whitenoise/domain/models/user_model.dart' as domain_user;
6+
import 'package:whitenoise/domain/models/user_profile.dart';
77
import 'package:whitenoise/src/rust/api/groups.dart' as groups_api;
88
import 'package:whitenoise/src/rust/api/messages.dart'
99
show ChatMessage, fetchAggregatedMessagesForGroup;
@@ -92,73 +92,73 @@ class GroupMessagesNotifier extends FamilyNotifier<GroupMessagesState, String> {
9292
if (activePubkey == null || activePubkey.isEmpty) {
9393
return {};
9494
}
95-
final groupContacts = await _fetchGroupUsersProfileData(activePubkey);
96-
final domainUsersMap = _mapContactModelsToDomainUsers(
95+
final groupUserProfiles = await _fetchGroupUserProfiles(activePubkey);
96+
final domainUsersMap = _mapUserProfilesToDomainUsers(
9797
activePubkey: activePubkey,
98-
contacts: groupContacts,
98+
userProfiles: groupUserProfiles,
9999
);
100100
return domainUsersMap;
101101
}
102102

103-
Future<List<MapEntry<String, ContactModel>>> _fetchUsersProfileData(
103+
Future<List<MapEntry<String, UserProfile>>> _fetchUserProfiles(
104104
List<String> pubkeys,
105105
) async {
106-
final userProfileDataNotifier = ref.read(userProfileDataProvider.notifier);
106+
final userProfileNotifier = ref.read(userProfileProvider.notifier);
107107
final userFutures = pubkeys.map(
108-
(pubkey) => userProfileDataNotifier
109-
.getUserProfileData(pubkey)
110-
.then((contact) => MapEntry(pubkey, contact)),
108+
(pubkey) => userProfileNotifier
109+
.getUserProfile(pubkey)
110+
.then((userProfile) => MapEntry(pubkey, userProfile)),
111111
);
112112
final usersProfileData = await Future.wait(userFutures);
113113
return usersProfileData;
114114
}
115115

116-
Future<List<MapEntry<String, ContactModel>>> _fetchGroupUsersProfileData(
116+
Future<List<MapEntry<String, UserProfile>>> _fetchGroupUserProfiles(
117117
String activePubkey,
118118
) async {
119119
final groupMembersPubkeys = await _groupMembers(
120120
pubkey: activePubkey,
121121
groupId: state.groupId,
122122
);
123-
final groupMembersUserProfileData = await _fetchUsersProfileData(groupMembersPubkeys);
124-
return groupMembersUserProfileData;
123+
final groupMembersUserProfile = await _fetchUserProfiles(groupMembersPubkeys);
124+
return groupMembersUserProfile;
125125
}
126126

127-
Map<String, domain_user.User> _mapContactModelsToDomainUsers({
127+
Map<String, domain_user.User> _mapUserProfilesToDomainUsers({
128128
required String activePubkey,
129-
required List<MapEntry<String, ContactModel>> contacts,
129+
required List<MapEntry<String, UserProfile>> userProfiles,
130130
}) {
131131
return Map<String, domain_user.User>.fromEntries(
132-
contacts.map(
132+
userProfiles.map(
133133
(entry) => MapEntry(
134134
entry.key,
135-
_contactModelToDomainUser(activePubkey: activePubkey, contact: entry.value),
135+
_userProfileToDomainUser(activePubkey: activePubkey, userProfile: entry.value),
136136
),
137137
),
138138
);
139139
}
140140

141141
String _getDisplayName({
142142
required String activePubkey,
143-
required ContactModel contact,
143+
required UserProfile userProfile,
144144
}) {
145-
if (_isMe(myPubkey: activePubkey, otherPubkey: contact.publicKey)) {
145+
if (_isMe(myPubkey: activePubkey, otherPubkey: userProfile.publicKey)) {
146146
return 'You';
147147
} else {
148-
return contact.displayName;
148+
return userProfile.displayName;
149149
}
150150
}
151151

152-
domain_user.User _contactModelToDomainUser({
152+
domain_user.User _userProfileToDomainUser({
153153
required String activePubkey,
154-
required ContactModel contact,
154+
required UserProfile userProfile,
155155
}) {
156156
return domain_user.User(
157-
id: contact.publicKey,
158-
displayName: _getDisplayName(activePubkey: activePubkey, contact: contact),
159-
nip05: contact.nip05 ?? '',
160-
publicKey: contact.publicKey,
161-
imagePath: contact.imagePath,
157+
id: userProfile.publicKey,
158+
displayName: _getDisplayName(activePubkey: activePubkey, userProfile: userProfile),
159+
nip05: userProfile.nip05 ?? '',
160+
publicKey: userProfile.publicKey,
161+
imagePath: userProfile.imagePath,
162162
);
163163
}
164164
}

lib/config/providers/group_provider.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ class GroupsNotifier extends Notifier<GroupsState> {
363363
try {
364364
final npub = _pubkeyFormatter(pubkey: memberPubkey).toNpub() ?? '';
365365

366-
// First try to get from follows (cached contacts)
366+
// First try to get from follows
367367
final followsNotifier = ref.read(followsProvider.notifier);
368368
final existingFollow = followsNotifier.findFollowByPubkey(memberPubkey);
369369

lib/config/providers/user_profile_data_provider.dart

Lines changed: 0 additions & 33 deletions
This file was deleted.
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import 'package:flutter_riverpod/flutter_riverpod.dart';
2+
import 'package:whitenoise/domain/models/user_profile.dart';
3+
import 'package:whitenoise/src/rust/api/metadata.dart' show FlutterMetadata;
4+
import 'package:whitenoise/src/rust/api/users.dart' as wn_users_api;
5+
import 'package:whitenoise/src/rust/api/users.dart' show User;
6+
7+
class UserProfileNotifier extends Notifier<void> {
8+
late final Future<User> Function({required String pubkey}) _wnApiGetUser;
9+
late final UserProfile Function({required String pubkey, required FlutterMetadata metadata})
10+
_getUserProfileFromMetadata;
11+
12+
UserProfileNotifier({
13+
Future<User> Function({required String pubkey})? wnApiGetUserFn,
14+
UserProfile Function({required String pubkey, required FlutterMetadata metadata})?
15+
getUserProfileFromMetadataFn,
16+
}) {
17+
_wnApiGetUser = wnApiGetUserFn ?? wn_users_api.getUser;
18+
_getUserProfileFromMetadata = getUserProfileFromMetadataFn ?? UserProfile.fromMetadata;
19+
}
20+
21+
@override
22+
void build() {}
23+
24+
Future<UserProfile> getUserProfile(String pubkey) async {
25+
final user = await _wnApiGetUser(pubkey: pubkey);
26+
final userProfile = _getUserProfileFromMetadata(pubkey: pubkey, metadata: user.metadata);
27+
return userProfile;
28+
}
29+
}
30+
31+
final userProfileProvider = NotifierProvider<UserProfileNotifier, void>(
32+
() => UserProfileNotifier(),
33+
);

lib/domain/models/contact_model.dart renamed to lib/domain/models/user_profile.dart

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import 'package:whitenoise/src/rust/api/metadata.dart' show FlutterMetadata;
33
import 'package:whitenoise/utils/pubkey_formatter.dart';
44
import 'package:whitenoise/utils/string_extensions.dart';
55

6-
class ContactModel {
6+
class UserProfile {
77
final String publicKey;
88
final String displayName;
99
final String? imagePath;
@@ -13,7 +13,7 @@ class ContactModel {
1313
final String? lud16;
1414
final String? _formattedPublicKey; // Cached formatted public key
1515

16-
ContactModel({
16+
UserProfile({
1717
required this.publicKey,
1818
required this.displayName,
1919
this.imagePath,
@@ -38,8 +38,8 @@ class ContactModel {
3838
}
3939
}
4040

41-
// Create ContactModel from Rust API Metadata with proper sanitization
42-
factory ContactModel.fromMetadata({
41+
// Create UserProfile from Rust API Metadata with proper sanitization
42+
factory UserProfile.fromMetadata({
4343
required String pubkey,
4444
FlutterMetadata? metadata,
4545
}) {
@@ -69,7 +69,7 @@ class ContactModel {
6969
formattedKey = pubkey.formatPublicKey();
7070
}
7171

72-
return ContactModel(
72+
return UserProfile(
7373
displayName: finalDisplayName,
7474
publicKey: npub,
7575
imagePath: picture,
@@ -104,7 +104,7 @@ class ContactModel {
104104
String get avatarLetter => displayName.isNotEmpty ? displayName[0].toUpperCase() : '?';
105105

106106
@override
107-
bool operator ==(covariant ContactModel other) {
107+
bool operator ==(covariant UserProfile other) {
108108
if (identical(this, other)) return true;
109109

110110
final hexNpub = PubkeyFormatter(pubkey: publicKey).toHex();

lib/domain/services/dm_chat_service.dart

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import 'package:flutter_riverpod/flutter_riverpod.dart';
22
import 'package:whitenoise/config/providers/group_provider.dart';
3-
import 'package:whitenoise/domain/models/contact_model.dart';
43
import 'package:whitenoise/domain/models/dm_chat_data.dart';
4+
import 'package:whitenoise/domain/models/user_profile.dart';
55
import 'package:whitenoise/src/rust/api/users.dart' as wn_users_api;
66
import 'package:whitenoise/utils/pubkey_formatter.dart';
77

@@ -18,14 +18,14 @@ class DMChatService {
1818
final user = await wn_users_api.getUser(pubkey: otherMember.publicKey);
1919
final otherMemberPubkey = otherMember.publicKey;
2020
final otherMemberNpubPubkey = PubkeyFormatter(pubkey: otherMemberPubkey).toNpub() ?? '';
21-
final contactModel = ContactModel.fromMetadata(
21+
final userProfile = UserProfile.fromMetadata(
2222
pubkey: otherMemberNpubPubkey,
2323
metadata: user.metadata,
2424
);
25-
final displayName = contactModel.displayName;
26-
final displayImage = contactModel.imagePath ?? (otherMember.imagePath ?? '');
27-
final nip05 = contactModel.nip05 ?? '';
28-
final npup = contactModel.publicKey;
25+
final displayName = userProfile.displayName;
26+
final displayImage = userProfile.imagePath ?? (otherMember.imagePath ?? '');
27+
final nip05 = userProfile.nip05 ?? '';
28+
final npup = userProfile.publicKey;
2929
return DMChatData(
3030
displayName: displayName,
3131
displayImage: displayImage,

lib/routing/router_provider.dart

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import 'package:whitenoise/ui/chat/chat_info/chat_info_screen.dart';
1212
import 'package:whitenoise/ui/chat/chat_info/edit_group_screen.dart';
1313
import 'package:whitenoise/ui/chat/chat_management/add_to_group_screen.dart';
1414
import 'package:whitenoise/ui/chat/chat_screen.dart';
15-
import 'package:whitenoise/ui/contact_list/chat_list_screen.dart';
1615
import 'package:whitenoise/ui/settings/app_settings/app_settings_screen.dart';
1716
import 'package:whitenoise/ui/settings/developer/developer_settings_screen.dart';
1817
import 'package:whitenoise/ui/settings/donate/donate_screen.dart';
@@ -23,6 +22,7 @@ import 'package:whitenoise/ui/settings/profile/share_profile_qr_scan_screen.dart
2322
import 'package:whitenoise/ui/settings/profile/share_profile_screen.dart';
2423
import 'package:whitenoise/ui/settings/profile_keys/profile_keys_screen.dart';
2524
import 'package:whitenoise/ui/settings/wallet/wallet_screen.dart';
25+
import 'package:whitenoise/ui/user_profile_list/chat_list_screen.dart';
2626

2727
/// Navigation observer that dismisses toasts when routes change
2828
class _NavigationObserver extends NavigatorObserver {
@@ -85,7 +85,7 @@ final routerProvider = Provider<GoRouter>((ref) {
8585
// If user is not authenticated and trying to access protected routes,
8686
// redirect to home
8787
if (!authState.isAuthenticated && !authState.isLoading) {
88-
final protectedRoutes = [Routes.chats, Routes.contacts, Routes.settings];
88+
final protectedRoutes = [Routes.chats, Routes.users, Routes.settings];
8989
if (protectedRoutes.any((route) => currentLocation.startsWith(route))) {
9090
return Routes.home;
9191
}
@@ -122,15 +122,15 @@ final routerProvider = Provider<GoRouter>((ref) {
122122
),
123123

124124
GoRoute(
125-
path: Routes.contacts,
125+
path: Routes.users,
126126
builder: (context, state) => const ChatListScreen(),
127127
routes: [
128128
GoRoute(
129129
path: ':id',
130130
builder: (context, state) {
131-
final contactId = state.pathParameters['id']!;
131+
final userId = state.pathParameters['id']!;
132132
return Scaffold(
133-
body: Center(child: Text('Contact Detail: $contactId')),
133+
body: Center(child: Text('User Detail: $userId')),
134134
);
135135
},
136136
),
@@ -213,14 +213,14 @@ final routerProvider = Provider<GoRouter>((ref) {
213213
],
214214
),
215215
GoRoute(
216-
path: Routes.contactQrScan,
216+
path: Routes.userProfileQrScan,
217217
builder: (context, state) => const ShareProfileQrScanScreen(hideViewQrButton: true),
218218
),
219219
GoRoute(
220-
path: Routes.addContactToGroup,
220+
path: Routes.addUserToGroup,
221221
builder: (context, state) {
222-
final contactNpub = state.pathParameters['id']!;
223-
return AddToGroupScreen(contactNpub: contactNpub);
222+
final userNpub = state.pathParameters['id']!;
223+
return AddToGroupScreen(userNpub: userNpub);
224224
},
225225
),
226226
],

lib/routing/routes.dart

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ abstract final class Routes {
1414
static const chatInfo = '/chats/:id/info';
1515
static const editGroup = '/chats/:id/info/edit';
1616

17-
// Contacts
18-
static const contacts = '/contacts';
19-
static const contact = '/contacts/:id';
17+
// Users
18+
static const users = '/users';
19+
static const user = '/users/:id';
2020

2121
// Settings
2222
static const settings = '/settings';
@@ -30,17 +30,17 @@ abstract final class Routes {
3030
static const settingsDonate = '/settings/donate';
3131
static const settingsShareProfile = '/settings/share_profile';
3232
static const settingsShareProfileQrScan = '/settings/share_profile/qr_scan';
33-
static const contactQrScan = '/contact/qr_scan';
33+
static const userProfileQrScan = '/user_profiles/qr_scan';
3434

3535
// misc
36-
static const addContactToGroup = '/add_to_group/:id';
36+
static const addUserToGroup = '/add_to_group/:id';
3737

3838
static void goToChat(BuildContext context, String chatId, {String? inviteId}) {
3939
GoRouter.of(context).go('/chats/$chatId', extra: inviteId);
4040
}
4141

42-
static void goToContact(BuildContext context, String contactId) {
43-
GoRouter.of(context).go('/contacts/$contactId');
42+
static void goToUser(BuildContext context, String userId) {
43+
GoRouter.of(context).go('/users/$userId');
4444
}
4545

4646
static void goToOnboarding(BuildContext context) {

lib/ui/chat/chat_info/widgets/group_member_bottom_sheet.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ class _GroupMemberBottomSheetState extends ConsumerState<GroupMemberBottomSheet>
256256
child: SendMessageButton(widget.member),
257257
),
258258
Flexible(
259-
child: AddToContactButton(widget.member),
259+
child: FollowToggleButton(widget.member),
260260
),
261261
],
262262
),
@@ -303,7 +303,7 @@ class _GroupMemberBottomSheetState extends ConsumerState<GroupMemberBottomSheet>
303303
),
304304
] else ...[
305305
Gap(8.h),
306-
AddToContactButton(widget.member),
306+
FollowToggleButton(widget.member),
307307
],
308308
],
309309
);

0 commit comments

Comments
 (0)