Skip to content

Commit

Permalink
runfix: Don't block app start with miriads of users (#6067)
Browse files Browse the repository at this point in the history
  • Loading branch information
AndyLnd authored Mar 12, 2019
1 parent 12588ee commit f11f933
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 30 deletions.
4 changes: 3 additions & 1 deletion src/page/template/list/start-ui.htm
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,9 @@
<!-- ko ifnot: isTeam() -->
<span class="start-ui-list-header" data-bind="text: t('searchConnections')"></span>
<!-- /ko -->
<user-list class="search-list-theme-black" params="user: contacts, click: clickOnContact, searchRepository: searchRepository, teamRepository: teamRepository, conversationRepository: conversationRepository"></user-list>
<!-- ko if: isVisible() -->
<user-list class="search-list-theme-black" params="user: contacts(), click: clickOnContact, searchRepository: searchRepository, teamRepository: teamRepository, conversationRepository: conversationRepository"></user-list>
<!-- /ko -->
</div>
<!-- /ko -->
<!-- /ko -->
Expand Down
4 changes: 2 additions & 2 deletions src/script/components/userList.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ z.components.UserList = class UserList {

// Filter all list items if a filter is provided
this.filteredUserEntities = ko.pureComputed(() => {
const connectedUsers = this.conversationRepository.getConnectedUsers();
const connectedUsers = this.conversationRepository.connectedUsers();
if (typeof this.filter === 'function') {
const normalizedQuery = z.search.SearchRepository.normalizeQuery(this.filter());
if (normalizedQuery) {
Expand Down Expand Up @@ -112,7 +112,7 @@ z.components.UserList = class UserList {

ko.components.register('user-list', {
template: `
<div class="search-list" data-bind="css: cssClasses(), foreach: {data: filteredUserEntities}">
<div class="search-list" data-bind="css: cssClasses(), foreach: {data: filteredUserEntities()}">
<participant-item params="participant: $data, customInfo: $parent.infos && $parent.infos()[$data.id], canSelect: $parent.isSelectEnabled, isSelected: $parent.isSelected($data), mode: $parent.mode" data-bind="click: $parent.onUserClick, css: {'no-underline': $parent.noUnderline, 'show-arrow': $parent.arrow, 'highlighted': $parent.highlightedUserIds.includes($data.id)}"></participant-item>
</div>
Expand Down
34 changes: 16 additions & 18 deletions src/script/conversation/ConversationRepository.js
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,22 @@ z.conversation.ConversationRepository = class ConversationRepository {
this.eventService,
{onMessageTimeout: this.handleMessageExpiration.bind(this)}
);

this.connectedUsers = ko.pureComputed(() => {
const inviterId = this.team_repository.memberInviters()[this.selfUser().id];
const inviter = inviterId ? this.user_repository.users().find(({id}) => id === inviterId) : null;
const connectedUsers = inviter ? [inviter] : [];
for (const conversation of this.conversations()) {
for (const user of conversation.participating_user_ets()) {
const isNotService = !user.isService;
const isNotIncluded = !connectedUsers.includes(user);
if (isNotService && isNotIncluded && (user.isTeamMember() || user.isConnected())) {
connectedUsers.push(user);
}
}
}
return connectedUsers;
});
}

checkMessageTimer(messageEntity) {
Expand Down Expand Up @@ -798,24 +814,6 @@ z.conversation.ConversationRepository = class ConversationRepository {
);
}

/**
* Get all the users that you are directly connected to.
* This means that the user either invited you, you are in a conversation with them or they are connected external users
* @returns {Array<User>} List of the connected users
*/
getConnectedUsers() {
const inviterId = this.team_repository.memberInviters()[this.selfUser().id];
const inviter = inviterId ? this.user_repository.users().find(({id}) => id === inviterId) : null;
const initialConnectedUsers = inviter ? [inviter] : [];
const allUsers = this.conversations().reduce((connectedUsers, conversation) => {
const users = conversation
.participating_user_ets()
.filter(user => !user.isService && (user.isTeamMember() || user.isConnected()));
return [...connectedUsers, ...users];
}, initialConnectedUsers);
return [...new Set(allUsers)];
}

/**
* Check for conversation locally and fetch it from the server otherwise.
* @param {string} conversation_id - ID of conversation to get
Expand Down
5 changes: 3 additions & 2 deletions src/script/team/TeamRepository.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,9 @@ z.team.TeamRepository = class TeamRepository {
this.memberRoles = ko.observable({});
this.memberInviters = ko.observable({});

this.isSelfConnectedTo = userId =>
this.memberRoles()[userId] !== ROLE.PARTNER || this.memberInviters()[userId] === this.selfUser().id;
this.isSelfConnectedTo = userId => {
return this.memberRoles()[userId] !== ROLE.PARTNER || this.memberInviters()[userId] === this.selfUser().id;
};

this.teamName = ko.pureComputed(() => (this.isTeam() ? this.team().name() : this.selfUser().name()));
this.teamSize = ko.pureComputed(() => (this.isTeam() ? this.teamMembers().length + 1 : 0));
Expand Down
15 changes: 8 additions & 7 deletions src/script/view_model/list/StartUIViewModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ z.viewModel.list.StartUIViewModel = class StartUIViewModel {
this.teamSize = this.teamRepository.teamSize;

this.state = ko.observable(StartUIViewModel.STATE.ADD_PEOPLE);
this.isVisible = ko.pureComputed(() => listViewModel.state() === z.viewModel.ListViewModel.STATE.START_UI);

this.peopleTabActive = ko.pureComputed(() => this.state() === StartUIViewModel.STATE.ADD_PEOPLE);

Expand All @@ -95,6 +96,9 @@ z.viewModel.list.StartUIViewModel = class StartUIViewModel {
this.searchInput = ko.observable('');
this.searchInput.subscribe(this.search);
this.isSearching = ko.pureComputed(() => this.searchInput().length);
this.showMatches = ko.observable(false);
const {canInviteTeamMembers, canSearchUnconnectedUsers} = generatePermissionHelpers();
this.showOnlyConnectedUsers = ko.pureComputed(() => !canSearchUnconnectedUsers(this.selfUser().teamRole()));

// User lists
this.contacts = ko.pureComputed(() => {
Expand All @@ -103,11 +107,11 @@ z.viewModel.list.StartUIViewModel = class StartUIViewModel {
}

if (this.showOnlyConnectedUsers()) {
return this.conversationRepository.getConnectedUsers();
return this.conversationRepository.connectedUsers();
}

if (this.isTeam()) {
const connectedUsers = this.conversationRepository.getConnectedUsers();
const connectedUsers = this.conversationRepository.connectedUsers();
const teamUsersWithoutPartners = this.teamRepository
.teamUsers()
.filter(user => connectedUsers.includes(user) || this.teamRepository.isSelfConnectedTo(user.id));
Expand Down Expand Up @@ -137,15 +141,12 @@ z.viewModel.list.StartUIViewModel = class StartUIViewModel {
this.showContent = ko.pureComputed(() => this.showContacts() || this.showMatches() || this.showSearchResults());
this.showCreateGuestRoom = ko.pureComputed(() => this.isTeam());
this.showInvitePeople = ko.pureComputed(() => !this.isTeam());
this.showMatches = ko.observable(false);

this.showNoContacts = ko.pureComputed(() => !this.isTeam() && !this.showContent());
const {canInviteTeamMembers, canSearchUnconnectedUsers} = generatePermissionHelpers();
this.showInviteMember = ko.pureComputed(
() => canInviteTeamMembers(this.selfUser().teamRole()) && this.teamSize() === 1
);

this.showOnlyConnectedUsers = ko.pureComputed(() => !canSearchUnconnectedUsers(this.selfUser().teamRole()));
this.showContacts = ko.pureComputed(() => this.contacts().length);

this.showNoMatches = ko.pureComputed(() => {
Expand Down Expand Up @@ -582,14 +583,14 @@ z.viewModel.list.StartUIViewModel = class StartUIViewModel {
const allLocalUsers = this.isTeam() ? this.teamRepository.teamUsers() : this.userRepository.connected_users();

const localSearchSources = this.showOnlyConnectedUsers()
? this.conversationRepository.getConnectedUsers()
? this.conversationRepository.connectedUsers()
: allLocalUsers;

const SEARCHABLE_FIELDS = z.search.SearchRepository.CONFIG.SEARCHABLE_FIELDS;
const searchFields = isHandle ? [SEARCHABLE_FIELDS.USERNAME] : undefined;

const contactResults = this.searchRepository.searchUserInSet(normalizedQuery, localSearchSources, searchFields);
const connectedUsers = this.conversationRepository.getConnectedUsers();
const connectedUsers = this.conversationRepository.connectedUsers();
const filteredResults = contactResults.filter(user => {
return (
connectedUsers.includes(user) ||
Expand Down

0 comments on commit f11f933

Please sign in to comment.