diff --git a/app/ui-sidenav/client/toolbar.js b/app/ui-sidenav/client/toolbar.js index fd31aa99d2ba..432a081253d2 100644 --- a/app/ui-sidenav/client/toolbar.js +++ b/app/ui-sidenav/client/toolbar.js @@ -35,19 +35,33 @@ const getFromServer = (cb, type) => { return false; } + let exactUser = null; + let exactRoom = null; + if (results.users[0] && results.users[0].username === currentFilter) { + exactUser = results.users.shift(); + } + if (results.rooms[0] && results.rooms[0].username === currentFilter) { + exactRoom = results.rooms.shift(); + } + const resultsFromServer = []; - resultsFromServer.push(...results.users.map((user) => ({ + const roomFilter = (room) => !resultsFromClient.find((item) => [item.rid, item._id].includes(room._id)); + const userMap = (user) => ({ _id: user._id, t: 'd', name: user.username, fname: user.name, - }))); + }); - resultsFromServer.push(...results.rooms.filter((room) => !resultsFromClient.find((item) => [item.rid, item._id].includes(room._id)))); + resultsFromServer.push(...results.users.map(userMap)); + resultsFromServer.push(...results.rooms.filter(roomFilter)); - if (resultsFromServer.length) { - cb(resultsFromClient.concat(resultsFromServer)); + if (resultsFromServer.length || exactUser || exactRoom) { + exactRoom = exactRoom ? [roomFilter(exactRoom)] : []; + exactUser = exactUser ? [userMap(exactUser)] : []; + const combinedResults = exactUser.concat(exactRoom, resultsFromClient, resultsFromServer); + cb(combinedResults); } }); }; diff --git a/server/publications/spotlight.js b/server/publications/spotlight.js index 0da321b49dfd..702ed843d139 100644 --- a/server/publications/spotlight.js +++ b/server/publications/spotlight.js @@ -19,7 +19,7 @@ function fetchRooms(userId, rooms) { } Meteor.methods({ - spotlight(text, usernames, type = { users: true, rooms: true }, rid) { + spotlight(text, usernames = [], type = { users: true, rooms: true }, rid) { const searchForChannels = text[0] === '#'; const searchForDMs = text[0] === '@'; if (searchForChannels) { @@ -72,7 +72,12 @@ Meteor.methods({ if (hasPermission(userId, 'view-outside-room')) { if (type.users === true && hasPermission(userId, 'view-d-room')) { - result.users = Users.findByActiveUsersExcept(text, usernames, userOptions).fetch(); + const exactUser = Users.findOneByUsernameIgnoringCase(text, userOptions); + if (exactUser && !usernames.includes(exactUser.username)) { + result.users.push(exactUser); + usernames.push(exactUser.username); + } + result.users = result.users.concat(Users.findByActiveUsersExcept(text, usernames, userOptions).fetch()); } if (type.rooms === true && hasPermission(userId, 'view-c-room')) { @@ -81,7 +86,13 @@ Meteor.methods({ .map((roomType) => roomType[0]); const roomIds = Subscriptions.findByUserIdAndTypes(userId, searchableRoomTypes, { fields: { rid: 1 } }).fetch().map((s) => s.rid); - result.rooms = fetchRooms(userId, Rooms.findByNameAndTypesNotInIds(regex, searchableRoomTypes, roomIds, roomOptions).fetch()); + const exactRoom = Rooms.findOneByNameAndType(text, searchableRoomTypes, roomOptions); + if (exactRoom) { + result.exactRoom.push(exactRoom); + roomIds.push(exactRoom.rid); + } + + result.rooms = result.rooms.concat(fetchRooms(userId, Rooms.findByNameAndTypesNotInIds(regex, searchableRoomTypes, roomIds, roomOptions).fetch())); } } else if (type.users === true && rid) { const subscriptions = Subscriptions.find({