Skip to content

Commit fae97c0

Browse files
authored
refactor: invite page redesign (#2186)
1 parent af923d6 commit fae97c0

File tree

5 files changed

+486
-139
lines changed

5 files changed

+486
-139
lines changed

assets/l10n/intl_en.arb

+5-1
Original file line numberDiff line numberDiff line change
@@ -4813,5 +4813,9 @@
48134813
"pleaseEnterInt": "Please enter a number",
48144814
"home": "Home",
48154815
"join": "Join",
4816-
"learnByTexting": "Learn by texting"
4816+
"learnByTexting": "Learn by texting",
4817+
"startChatting": "Start chatting",
4818+
"referFriends": "Refer friends",
4819+
"referFriendDialogTitle": "Invite a friend to your conversation",
4820+
"referFriendDialogDesc": "Do you have a friend who is excited to learn a new language with you? Then copy and send this invitation link to join and start chatting with you today."
48174821
}

lib/pages/invitation_selection/invitation_selection.dart

+87-74
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,82 @@ class InvitationSelectionController extends State<InvitationSelection> {
3434

3535
String? get roomId => widget.roomId;
3636

37+
// #Pangea
38+
List<User>? get participants {
39+
final room = Matrix.of(context).client.getRoomById(roomId!);
40+
return room?.getParticipants();
41+
}
42+
43+
List<Membership> get _membershipOrder => [
44+
Membership.join,
45+
Membership.invite,
46+
Membership.knock,
47+
Membership.leave,
48+
Membership.ban,
49+
];
50+
51+
String? membershipCopy(Membership? membership) => switch (membership) {
52+
Membership.ban => L10n.of(context).banned,
53+
Membership.invite => L10n.of(context).invited,
54+
Membership.join => null,
55+
Membership.knock => L10n.of(context).knocking,
56+
Membership.leave => L10n.of(context).leftTheChat,
57+
null => null,
58+
};
59+
60+
int _sortUsers(User a, User b) {
61+
// sort yourself to the top
62+
final client = Matrix.of(context).client;
63+
if (a.id == client.userID) return -1;
64+
if (b.id == client.userID) return 1;
65+
66+
// sort the bot to the bottom
67+
if (a.id == BotName.byEnvironment) return 1;
68+
if (b.id == BotName.byEnvironment) return -1;
69+
70+
if (participants != null) {
71+
final participantA = participants!.firstWhereOrNull((u) => u.id == a.id);
72+
final participantB = participants!.firstWhereOrNull((u) => u.id == b.id);
73+
// sort all participants first, with admins first, then moderators, then the rest
74+
if (participantA?.membership == null &&
75+
participantB?.membership != null) {
76+
return 1;
77+
}
78+
if (participantA?.membership != null &&
79+
participantB?.membership == null) {
80+
return -1;
81+
}
82+
if (participantA?.membership != null &&
83+
participantB?.membership != null) {
84+
final aIndex = _membershipOrder.indexOf(participantA!.membership);
85+
final bIndex = _membershipOrder.indexOf(participantB!.membership);
86+
if (aIndex != bIndex) {
87+
return aIndex.compareTo(bIndex);
88+
}
89+
}
90+
}
91+
92+
// finally, sort by displayname
93+
final aName = a.calcDisplayname().toLowerCase();
94+
final bName = b.calcDisplayname().toLowerCase();
95+
return aName.compareTo(bName);
96+
}
97+
// Pangea#
98+
3799
Future<List<User>> getContacts(BuildContext context) async {
38100
final client = Matrix.of(context).client;
39101
final room = client.getRoomById(roomId!)!;
40102

41103
final participants = (room.summary.mJoinedMemberCount ?? 0) > 100
42104
? room.getParticipants()
43-
: await room.requestParticipants();
105+
// #Pangea
106+
// : await room.requestParticipants();
107+
: await room.requestParticipants(
108+
[Membership.join, Membership.invite, Membership.knock],
109+
false,
110+
true,
111+
);
112+
// Pangea#
44113
participants.removeWhere(
45114
(u) => ![Membership.join, Membership.invite].contains(u.membership),
46115
);
@@ -53,16 +122,26 @@ class InvitationSelectionController extends State<InvitationSelection> {
53122
.getParticipants()
54123
.firstWhereOrNull((u) => u.id != client.userID),
55124
)
125+
.where((u) => u != null)
126+
.cast<User>()
56127
// Pangea#
57128
.toList();
58129
// #Pangea
59-
contacts.removeWhere((u) => u == null || u.id != BotName.byEnvironment);
60-
contacts.sort(
61-
(a, b) => a!.calcDisplayname().toLowerCase().compareTo(
62-
b!.calcDisplayname().toLowerCase(),
63-
),
64-
);
65-
return contacts.cast<User>();
130+
final mutuals = client.rooms
131+
.where((r) => r.isSpace)
132+
.map((r) => r.getParticipants())
133+
.expand((element) => element)
134+
.toList();
135+
136+
for (final user in mutuals) {
137+
final index = contacts.indexWhere((u) => u.id == user.id);
138+
if (index == -1) {
139+
contacts.add(user);
140+
}
141+
}
142+
143+
contacts.sort(_sortUsers);
144+
return contacts;
66145
// contacts.sort(
67146
// (a, b) => a.calcDisplayname().toLowerCase().compareTo(
68147
// b.calcDisplayname().toLowerCase(),
@@ -72,72 +151,6 @@ class InvitationSelectionController extends State<InvitationSelection> {
72151
//Pangea#
73152
}
74153

75-
//#Pangea
76-
// // add all students (already local) from spaceParents who aren't already in room to eligibleStudents
77-
// // use room.members to get all users in room
78-
// bool _initialized = false;
79-
// Future<List<User>> eligibleStudents(
80-
// BuildContext context,
81-
// String text,
82-
// ) async {
83-
// if (!_initialized) {
84-
// _initialized = true;
85-
// await requestParentSpaceParticipants();
86-
// }
87-
88-
// final eligibleStudents = <User>[];
89-
// final spaceParents = room?.pangeaSpaceParents;
90-
// if (spaceParents == null) return eligibleStudents;
91-
92-
// final userId = Matrix.of(context).client.userID;
93-
// for (final Room space in spaceParents) {
94-
// eligibleStudents.addAll(
95-
// space.getParticipants().where(
96-
// (spaceUser) =>
97-
// spaceUser.id != BotName.byEnvironment &&
98-
// spaceUser.id != "@support:staging.pangea.chat" &&
99-
// spaceUser.id != userId &&
100-
// (text.isEmpty ||
101-
// (spaceUser.displayName
102-
// ?.toLowerCase()
103-
// .contains(text.toLowerCase()) ??
104-
// false) ||
105-
// spaceUser.id.toLowerCase().contains(text.toLowerCase())),
106-
// ),
107-
// );
108-
// }
109-
// return eligibleStudents;
110-
// }
111-
112-
// Future<SearchUserDirectoryResponse>
113-
// eligibleStudentsAsSearchUserDirectoryResponse(
114-
// BuildContext context,
115-
// String text,
116-
// ) async {
117-
// return SearchUserDirectoryResponse(
118-
// results: (await eligibleStudents(context, text))
119-
// .map(
120-
// (e) => Profile(
121-
// userId: e.id,
122-
// avatarUrl: e.avatarUrl,
123-
// displayName: e.displayName,
124-
// ),
125-
// )
126-
// .toList(),
127-
// limited: false,
128-
// );
129-
// }
130-
131-
// List<User?> studentsInRoom(BuildContext context) =>
132-
// room
133-
// ?.getParticipants()
134-
// .where(
135-
// (u) => [Membership.join, Membership.invite].contains(u.membership),
136-
// )
137-
// .toList() ??
138-
// <User>[];
139-
//Pangea#
140-
141154
void inviteAction(BuildContext context, String id, String displayname) async {
142155
final room = Matrix.of(context).client.getRoomById(roomId!)!;
143156

0 commit comments

Comments
 (0)