moodle/message/amd/build/message_drawer_view_search.min.js.map
2023-03-09 09:53:19 +08:00

1 line
44 KiB
Plaintext

{"version":3,"file":"message_drawer_view_search.min.js","sources":["../src/message_drawer_view_search.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Controls the search page of the message drawer.\n *\n * @module core_message/message_drawer_view_search\n * @copyright 2018 Ryan Wyllie <ryan@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine(\n[\n 'jquery',\n 'core/custom_interaction_events',\n 'core/notification',\n 'core/pubsub',\n 'core/str',\n 'core/templates',\n 'core_message/message_repository',\n 'core_message/message_drawer_events',\n],\nfunction(\n $,\n CustomEvents,\n Notification,\n PubSub,\n Str,\n Templates,\n Repository,\n Events\n) {\n\n var MESSAGE_SEARCH_LIMIT = 50;\n var USERS_SEARCH_LIMIT = 50;\n var USERS_INITIAL_SEARCH_LIMIT = 3;\n\n var SELECTORS = {\n BLOCK_ICON_CONTAINER: '[data-region=\"block-icon-container\"]',\n CANCEL_SEARCH_BUTTON: '[data-action=\"cancel-search\"]',\n CONTACTS_CONTAINER: '[data-region=\"contacts-container\"]',\n CONTACTS_LIST: '[data-region=\"contacts-container\"] [data-region=\"list\"]',\n EMPTY_MESSAGE_CONTAINER: '[data-region=\"empty-message-container\"]',\n LIST: '[data-region=\"list\"]',\n LOADING_ICON_CONTAINER: '[data-region=\"loading-icon-container\"]',\n LOADING_PLACEHOLDER: '[data-region=\"loading-placeholder\"]',\n MESSAGES_LIST: '[data-region=\"messages-container\"] [data-region=\"list\"]',\n MESSAGES_CONTAINER: '[data-region=\"messages-container\"]',\n NON_CONTACTS_CONTAINER: '[data-region=\"non-contacts-container\"]',\n NON_CONTACTS_LIST: '[data-region=\"non-contacts-container\"] [data-region=\"list\"]',\n SEARCH_ICON_CONTAINER: '[data-region=\"search-icon-container\"]',\n SEARCH_ACTION: '[data-action=\"search\"]',\n SEARCH_INPUT: '[data-region=\"search-input\"]',\n SEARCH_RESULTS_CONTAINER: '[data-region=\"search-results-container\"]',\n LOAD_MORE_USERS: '[data-action=\"load-more-users\"]',\n LOAD_MORE_MESSAGES: '[data-action=\"load-more-messages\"]',\n BUTTON_TEXT: '[data-region=\"button-text\"]',\n NO_RESULTS_CONTAINTER: '[data-region=\"no-results-container\"]',\n ALL_CONTACTS_CONTAINER: '[data-region=\"all-contacts-container\"]'\n };\n\n var TEMPLATES = {\n CONTACTS_LIST: 'core_message/message_drawer_contacts_list',\n NON_CONTACTS_LIST: 'core_message/message_drawer_non_contacts_list',\n MESSAGES_LIST: 'core_message/message_drawer_messages_list'\n };\n\n /**\n * Get the logged in user id.\n *\n * @param {Object} body Search body container element.\n * @return {Number} User id.\n */\n var getLoggedInUserId = function(body) {\n return body.attr('data-user-id');\n };\n\n /**\n * Show the no messages container element.\n *\n * @param {Object} body Search body container element.\n * @return {Object} No messages container element.\n */\n var getEmptyMessageContainer = function(body) {\n return body.find(SELECTORS.EMPTY_MESSAGE_CONTAINER);\n };\n\n /**\n * Get the search loading icon.\n *\n * @param {Object} header Search header container element.\n * @return {Object} Loading icon element.\n */\n var getLoadingIconContainer = function(header) {\n return header.find(SELECTORS.LOADING_ICON_CONTAINER);\n };\n\n /**\n * Get the loading container element.\n *\n * @param {Object} body Search body container element.\n * @return {Object} Loading container element.\n */\n var getLoadingPlaceholder = function(body) {\n return body.find(SELECTORS.LOADING_PLACEHOLDER);\n };\n\n /**\n * Get the search icon container.\n *\n * @param {Object} header Search header container element.\n * @return {Object} Search icon container.\n */\n var getSearchIconContainer = function(header) {\n return header.find(SELECTORS.SEARCH_ICON_CONTAINER);\n };\n\n /**\n * Get the search input container.\n *\n * @param {Object} header Search header container element.\n * @return {Object} Search input container.\n */\n var getSearchInput = function(header) {\n return header.find(SELECTORS.SEARCH_INPUT);\n };\n\n /**\n * Get the search results container.\n *\n * @param {Object} body Search body container element.\n * @return {Object} Search results container.\n */\n var getSearchResultsContainer = function(body) {\n return body.find(SELECTORS.SEARCH_RESULTS_CONTAINER);\n };\n\n /**\n * Get the search contacts container.\n *\n * @param {Object} body Search body container element.\n * @return {Object} Search contacts container.\n */\n var getContactsContainer = function(body) {\n return body.find(SELECTORS.CONTACTS_CONTAINER);\n };\n\n /**\n * Get the search non contacts container.\n *\n * @param {Object} body Search body container element.\n * @return {Object} Search non contacts container.\n */\n var getNonContactsContainer = function(body) {\n return body.find(SELECTORS.NON_CONTACTS_CONTAINER);\n };\n\n /**\n * Get the search messages container.\n *\n * @param {Object} body Search body container element.\n * @return {Object} Search messages container.\n */\n var getMessagesContainer = function(body) {\n return body.find(SELECTORS.MESSAGES_CONTAINER);\n };\n\n\n /**\n * Show the messages empty container.\n *\n * @param {Object} body Search body container element.\n */\n var showEmptyMessage = function(body) {\n getEmptyMessageContainer(body).removeClass('hidden');\n };\n\n /**\n * Hide the messages empty container.\n *\n * @param {Object} body Search body container element.\n */\n var hideEmptyMessage = function(body) {\n getEmptyMessageContainer(body).addClass('hidden');\n };\n\n\n /**\n * Show the loading icon.\n *\n * @param {Object} header Search header container element.\n */\n var showLoadingIcon = function(header) {\n getLoadingIconContainer(header).removeClass('hidden');\n };\n\n /**\n * Hide the loading icon.\n *\n * @param {Object} header Search header container element.\n */\n var hideLoadingIcon = function(header) {\n getLoadingIconContainer(header).addClass('hidden');\n };\n\n /**\n * Show loading placeholder.\n *\n * @param {Object} body Search body container element.\n */\n var showLoadingPlaceholder = function(body) {\n getLoadingPlaceholder(body).removeClass('hidden');\n };\n\n /**\n * Hide loading placeholder.\n *\n * @param {Object} body Search body container element.\n */\n var hideLoadingPlaceholder = function(body) {\n getLoadingPlaceholder(body).addClass('hidden');\n };\n\n /**\n * Show search icon.\n *\n * @param {Object} header Search header container element.\n */\n var showSearchIcon = function(header) {\n getSearchIconContainer(header).removeClass('hidden');\n };\n\n /**\n * Hide search icon.\n *\n * @param {Object} header Search header container element.\n */\n var hideSearchIcon = function(header) {\n getSearchIconContainer(header).addClass('hidden');\n };\n\n /**\n * Show search results.\n *\n * @param {Object} body Search body container element.\n */\n var showSearchResults = function(body) {\n getSearchResultsContainer(body).removeClass('hidden');\n };\n\n /**\n * Hide search results.\n *\n * @param {Object} body Search body container element.\n */\n var hideSearchResults = function(body) {\n getSearchResultsContainer(body).addClass('hidden');\n };\n\n /**\n * Show the no search results message.\n *\n * @param {Object} body Search body container element.\n */\n var showNoSearchResults = function(body) {\n var container = getSearchResultsContainer(body);\n container.find(SELECTORS.ALL_CONTACTS_CONTAINER).addClass('hidden');\n container.find(SELECTORS.MESSAGES_CONTAINER).addClass('hidden');\n container.find(SELECTORS.NO_RESULTS_CONTAINTER).removeClass('hidden');\n };\n\n /**\n * Hide the no search results message.\n *\n * @param {Object} body Search body container element.\n */\n var hideNoSearchResults = function(body) {\n var container = getSearchResultsContainer(body);\n container.find(SELECTORS.ALL_CONTACTS_CONTAINER).removeClass('hidden');\n container.find(SELECTORS.MESSAGES_CONTAINER).removeClass('hidden');\n container.find(SELECTORS.NO_RESULTS_CONTAINTER).addClass('hidden');\n };\n\n /**\n * Show the whole contacts results area.\n *\n * @param {Object} body Search body container element.\n */\n var showAllContactsSearchResults = function(body) {\n var container = getSearchResultsContainer(body);\n container.find(SELECTORS.ALL_CONTACTS_CONTAINER).removeClass('hidden');\n };\n\n /**\n * Hide the whole contacts results area.\n *\n * @param {Object} body Search body container element.\n */\n var hideAllContactsSearchResults = function(body) {\n var container = getSearchResultsContainer(body);\n container.find(SELECTORS.ALL_CONTACTS_CONTAINER).addClass('hidden');\n };\n\n /**\n * Show the contacts results.\n *\n * @param {Object} body Search body container element.\n */\n var showContactsSearchResults = function(body) {\n var container = getSearchResultsContainer(body);\n container.find(SELECTORS.CONTACTS_CONTAINER).removeClass('hidden');\n };\n\n /**\n * Hide the contacts results.\n *\n * @param {Object} body Search body container element.\n */\n var hideContactsSearchResults = function(body) {\n var container = getSearchResultsContainer(body);\n container.find(SELECTORS.CONTACTS_CONTAINER).addClass('hidden');\n };\n\n /**\n * Show the non contacts results.\n *\n * @param {Object} body Search body container element.\n */\n var showNonContactsSearchResults = function(body) {\n var container = getSearchResultsContainer(body);\n container.find(SELECTORS.NON_CONTACTS_CONTAINER).removeClass('hidden');\n };\n\n /**\n * Hide the non contacts results.\n *\n * @param {Object} body Search body container element.\n */\n var hideNonContactsSearchResults = function(body) {\n var container = getSearchResultsContainer(body);\n container.find(SELECTORS.NON_CONTACTS_CONTAINER).addClass('hidden');\n };\n\n /**\n * Show the messages results.\n *\n * @param {Object} body Search body container element.\n */\n var showMessagesSearchResults = function(body) {\n var container = getSearchResultsContainer(body);\n container.find(SELECTORS.MESSAGES_CONTAINER).removeClass('hidden');\n };\n\n /**\n * Hide the messages results.\n *\n * @param {Object} body Search body container element.\n */\n var hideMessagesSearchResults = function(body) {\n var container = getSearchResultsContainer(body);\n container.find(SELECTORS.MESSAGES_CONTAINER).addClass('hidden');\n };\n\n /**\n * Disable the search input.\n *\n * @param {Object} header Search header container element.\n */\n var disableSearchInput = function(header) {\n getSearchInput(header).prop('disabled', true);\n };\n\n /**\n * Enable the search input.\n *\n * @param {Object} header Search header container element.\n */\n var enableSearchInput = function(header) {\n getSearchInput(header).prop('disabled', false);\n };\n\n /**\n * Clear the search input.\n *\n * @param {Object} header Search header container element.\n */\n var clearSearchInput = function(header) {\n getSearchInput(header).val('');\n };\n\n /**\n * Clear all search results\n *\n * @param {Object} body Search body container element.\n */\n var clearAllSearchResults = function(body) {\n body.find(SELECTORS.CONTACTS_LIST).empty();\n body.find(SELECTORS.NON_CONTACTS_LIST).empty();\n body.find(SELECTORS.MESSAGES_LIST).empty();\n hideNoSearchResults(body);\n showAllContactsSearchResults(body);\n showContactsSearchResults(body);\n showNonContactsSearchResults(body);\n showMessagesSearchResults(body);\n showLoadMoreUsersButton(body);\n showLoadMoreMessagesButton(body);\n };\n\n /**\n * Update the body and header to indicate the search is loading.\n *\n * @param {Object} header Search header container element.\n * @param {Object} body Search body container element.\n */\n var startLoading = function(header, body) {\n hideSearchIcon(header);\n hideEmptyMessage(body);\n hideSearchResults(body);\n showLoadingIcon(header);\n showLoadingPlaceholder(body);\n disableSearchInput(header);\n };\n\n /**\n * Update the body and header to indicate the search has stopped loading.\n *\n * @param {Object} header Search header container element.\n * @param {Object} body Search body container element.\n */\n var stopLoading = function(header, body) {\n showSearchIcon(header);\n hideEmptyMessage(body);\n showSearchResults(body);\n hideLoadingIcon(header);\n hideLoadingPlaceholder(body);\n enableSearchInput(header);\n };\n\n /**\n * Show the more users loading icon.\n *\n * @param {Object} root The more users container element.\n */\n var showUsersLoadingIcon = function(root) {\n var button = root.find(SELECTORS.LOAD_MORE_USERS);\n button.prop('disabled', true);\n button.find(SELECTORS.BUTTON_TEXT).addClass('hidden');\n button.find(SELECTORS.LOADING_ICON_CONTAINER).removeClass('hidden');\n };\n\n /**\n * Hide the more users loading icon.\n *\n * @param {Object} root The more users container element.\n */\n var hideUsersLoadingIcon = function(root) {\n var button = root.find(SELECTORS.LOAD_MORE_USERS);\n button.prop('disabled', false);\n button.find(SELECTORS.BUTTON_TEXT).removeClass('hidden');\n button.find(SELECTORS.LOADING_ICON_CONTAINER).addClass('hidden');\n };\n\n /**\n * Show the load more users button.\n *\n * @param {Object} root The users container element.\n */\n var showLoadMoreUsersButton = function(root) {\n root.find(SELECTORS.LOAD_MORE_USERS).removeClass('hidden');\n };\n\n /**\n * Hide the load more users button.\n *\n * @param {Object} root The users container element.\n */\n var hideLoadMoreUsersButton = function(root) {\n root.find(SELECTORS.LOAD_MORE_USERS).addClass('hidden');\n };\n\n /**\n * Show the messages are loading icon.\n *\n * @param {Object} root Messages root element.\n */\n var showMessagesLoadingIcon = function(root) {\n var button = root.find(SELECTORS.LOAD_MORE_MESSAGES);\n button.prop('disabled', true);\n button.find(SELECTORS.BUTTON_TEXT).addClass('hidden');\n button.find(SELECTORS.LOADING_ICON_CONTAINER).removeClass('hidden');\n };\n\n /**\n * Hide the messages are loading icon.\n *\n * @param {Object} root Messages root element.\n */\n var hideMessagesLoadingIcon = function(root) {\n var button = root.find(SELECTORS.LOAD_MORE_MESSAGES);\n button.prop('disabled', false);\n button.find(SELECTORS.BUTTON_TEXT).removeClass('hidden');\n button.find(SELECTORS.LOADING_ICON_CONTAINER).addClass('hidden');\n };\n\n /**\n * Show the load more messages button.\n *\n * @param {Object} root The messages container element.\n */\n var showLoadMoreMessagesButton = function(root) {\n root.find(SELECTORS.LOAD_MORE_MESSAGES).removeClass('hidden');\n };\n\n /**\n * Hide the load more messages button.\n *\n * @param {Object} root The messages container element.\n */\n var hideLoadMoreMessagesButton = function(root) {\n root.find(SELECTORS.LOAD_MORE_MESSAGES).addClass('hidden');\n };\n\n /**\n * Find a contact in the search results.\n *\n * @param {Object} root Search results container element.\n * @param {Number} userId User id.\n * @return {Object} User container element.\n */\n var findContact = function(root, userId) {\n return root.find('[data-contact-user-id=\"' + userId + '\"]');\n };\n\n /**\n * Add a contact to the search results.\n *\n * @param {Object} root Search results container.\n * @param {Object} contact User in contacts list.\n */\n var addContact = function(root, contact) {\n var nonContactsContainer = getNonContactsContainer(root);\n var nonContact = findContact(nonContactsContainer, contact.userid);\n\n if (nonContact.length) {\n nonContact.remove();\n var contactsContainer = getContactsContainer(root);\n contactsContainer.removeClass('hidden');\n contactsContainer.find(SELECTORS.LIST).append(nonContact);\n }\n\n if (!nonContactsContainer.find(SELECTORS.LIST).children().length) {\n nonContactsContainer.addClass('hidden');\n }\n };\n\n /**\n * Remove a contact from the contacts results.\n *\n * @param {Object} root Search results container.\n * @param {Object} userId Contact user id.\n */\n var removeContact = function(root, userId) {\n var contactsContainer = getContactsContainer(root);\n var contact = findContact(contactsContainer, userId);\n\n if (contact.length) {\n contact.remove();\n var nonContactsContainer = getNonContactsContainer(root);\n nonContactsContainer.removeClass('hidden');\n nonContactsContainer.find(SELECTORS.LIST).append(contact);\n }\n\n if (!contactsContainer.find(SELECTORS.LIST).children().length) {\n contactsContainer.addClass('hidden');\n }\n };\n\n /**\n * Show the contact is blocked icon.\n *\n * @param {Object} root Search results container.\n * @param {Object} userId Contact user id.\n */\n var blockContact = function(root, userId) {\n var contact = findContact(root, userId);\n if (contact.length) {\n contact.find(SELECTORS.BLOCK_ICON_CONTAINER).removeClass('hidden');\n }\n };\n\n /**\n * Hide the contact is blocked icon.\n *\n * @param {Object} root Search results container.\n * @param {Object} userId Contact user id.\n */\n var unblockContact = function(root, userId) {\n var contact = findContact(root, userId);\n if (contact.length) {\n contact.find(SELECTORS.BLOCK_ICON_CONTAINER).addClass('hidden');\n }\n };\n\n /**\n * Highlight words in search results.\n *\n * @param {String} content HTML to search.\n * @param {String} searchText Search text.\n * @return {String} searchText with search wrapped in matchtext span.\n */\n var highlightSearch = function(content, searchText) {\n if (!content) {\n return '';\n }\n var regex = new RegExp('(' + searchText + ')', 'gi');\n return content.replace(regex, '<span class=\"matchtext\">$1</span>');\n };\n\n\n /**\n * Render contacts in the contacts search results.\n *\n * @param {Object} root Search results container.\n * @param {Array} contacts List of contacts.\n * @return {Promise} Renderer promise.\n */\n var renderContacts = function(root, contacts) {\n var container = getContactsContainer(root);\n var frompanel = root.attr('data-in-panel');\n var list = container.find(SELECTORS.LIST);\n\n return Templates.render(TEMPLATES.CONTACTS_LIST, {contacts: contacts, frompanel: frompanel})\n .then(function(html) {\n list.append(html);\n return html;\n });\n };\n\n /**\n * Render non contacts in the contacts search results.\n *\n * @param {Object} root Search results container.\n * @param {Array} nonContacts List of non contacts.\n * @return {Promise} Renderer promise.\n */\n var renderNonContacts = function(root, nonContacts) {\n var container = getNonContactsContainer(root);\n var frompanel = root.attr('data-in-panel');\n var list = container.find(SELECTORS.LIST);\n\n return Templates.render(TEMPLATES.NON_CONTACTS_LIST, {noncontacts: nonContacts, frompanel: frompanel})\n .then(function(html) {\n list.append(html);\n return html;\n });\n };\n\n /**\n * Render messages in the messages search results.\n *\n * @param {Object} root Search results container.\n * @param {Array} messages List of messages.\n * @return {Promise} Renderer promise.\n */\n var renderMessages = function(root, messages) {\n var container = getMessagesContainer(root);\n var frompanel = root.attr('data-in-panel');\n var list = container.find(SELECTORS.LIST);\n\n return Templates.render(TEMPLATES.MESSAGES_LIST, {messages: messages, frompanel: frompanel})\n .then(function(html) {\n list.append(html);\n return html;\n });\n };\n\n /**\n * Load more users from the repository and render the results into the users search results.\n *\n * @param {Object} root Search results container.\n * @param {Number} loggedInUserId Current logged in user.\n * @param {String} text Search text.\n * @param {Number} limit Number of users to get.\n * @param {Number} offset Load users from\n * @return {Object} jQuery promise\n */\n var loadMoreUsers = function(root, loggedInUserId, text, limit, offset) {\n var loadedAll = false;\n showUsersLoadingIcon(root);\n\n return Repository.searchUsers(loggedInUserId, text, limit + 1, offset)\n .then(function(results) {\n var contacts = results.contacts;\n var noncontacts = results.noncontacts;\n\n if (contacts.length <= limit && noncontacts.length <= limit) {\n loadedAll = true;\n return {\n contacts: contacts,\n noncontacts: noncontacts\n };\n } else {\n return {\n contacts: contacts.slice(0, limit),\n noncontacts: noncontacts.slice(0, limit)\n };\n }\n })\n .then(function(results) {\n var contactsCount = results.contacts.length;\n var nonContactsCount = results.noncontacts.length;\n\n if (contactsCount) {\n results.contacts.forEach(function(contact) {\n contact.highlight = highlightSearch(contact.fullname, text);\n });\n }\n\n if (nonContactsCount) {\n results.noncontacts.forEach(function(contact) {\n contact.highlight = highlightSearch(contact.fullname, text);\n });\n }\n\n return $.when(\n contactsCount ? renderContacts(root, results.contacts) : true,\n nonContactsCount ? renderNonContacts(root, results.noncontacts) : true\n )\n .then(function() {\n return {\n contactsCount: contactsCount,\n nonContactsCount: nonContactsCount\n };\n });\n })\n .then(function(counts) {\n hideUsersLoadingIcon(root);\n\n if (loadedAll) {\n hideLoadMoreUsersButton(root);\n }\n\n return counts;\n })\n .catch(function(error) {\n hideUsersLoadingIcon(root);\n // Rethrow error for other handlers.\n throw error;\n });\n };\n\n /**\n * Load more messages from the repository and render the results into the messages search results.\n *\n * @param {Object} root Search results container.\n * @param {Number} loggedInUserId Current logged in user.\n * @param {String} text Search text.\n * @param {Number} limit Number of messages to get.\n * @param {Number} offset Load messages from\n * @return {Object} jQuery promise\n */\n var loadMoreMessages = function(root, loggedInUserId, text, limit, offset) {\n var loadedAll = false;\n showMessagesLoadingIcon(root);\n\n return Repository.searchMessages(loggedInUserId, text, limit + 1, offset)\n .then(function(results) {\n var messages = results.contacts;\n\n if (messages.length <= limit) {\n loadedAll = true;\n return messages;\n } else {\n return messages.slice(0, limit);\n }\n })\n .then(function(messages) {\n if (messages.length) {\n messages.forEach(function(message) {\n message.lastmessage = highlightSearch(message.lastmessage, text);\n });\n return renderMessages(root, messages)\n .then(function() {\n return messages.length;\n });\n } else {\n return messages.length;\n }\n })\n .then(function(count) {\n hideMessagesLoadingIcon(root);\n\n if (loadedAll) {\n hideLoadMoreMessagesButton(root);\n }\n\n return count;\n })\n .catch(function(error) {\n hideMessagesLoadingIcon(root);\n // Rethrow error for other handlers.\n throw error;\n });\n };\n\n /**\n * Search for users and messages.\n *\n * @param {Object} header Search header container element.\n * @param {Object} body Search body container element.\n * @param {String} searchText Search text.\n * @param {Number} usersLimit The users limit.\n * @param {Number} usersOffset The users offset.\n * @param {Number} messagesLimit The message limit.\n * @param {Number} messagesOffset The message offset.\n * @return {Object} jQuery promise\n */\n var search = function(header, body, searchText, usersLimit, usersOffset, messagesLimit, messagesOffset) {\n var loggedInUserId = getLoggedInUserId(body);\n startLoading(header, body);\n clearAllSearchResults(body);\n\n return $.when(\n loadMoreUsers(body, loggedInUserId, searchText, usersLimit, usersOffset),\n loadMoreMessages(body, loggedInUserId, searchText, messagesLimit, messagesOffset)\n )\n .then(function(userCounts, messagesCount) {\n var contactsCount = userCounts.contactsCount;\n var nonContactsCount = userCounts.nonContactsCount;\n\n stopLoading(header, body);\n\n if (!contactsCount && !nonContactsCount && !messagesCount) {\n showNoSearchResults(body);\n } else {\n if (!contactsCount && !nonContactsCount) {\n hideAllContactsSearchResults(body);\n } else {\n if (!contactsCount) {\n hideContactsSearchResults(body);\n }\n\n if (!nonContactsCount) {\n hideNonContactsSearchResults(body);\n }\n }\n\n if (!messagesCount) {\n hideMessagesSearchResults(body);\n }\n }\n\n return;\n });\n };\n\n\n /**\n * Listen to and handle events for searching.\n *\n * @param {Object} header Search header container element.\n * @param {Object} body Search body container element.\n */\n var registerEventListeners = function(header, body) {\n var loggedInUserId = getLoggedInUserId(body);\n var searchInput = getSearchInput(header);\n var searchText = '';\n var messagesOffset = 0;\n var usersOffset = 0;\n\n var searchEventHandler = function(e, data) {\n searchText = searchInput.val().trim();\n\n if (searchText !== '') {\n messagesOffset = 0;\n usersOffset = 0;\n search(\n header,\n body,\n searchText,\n USERS_INITIAL_SEARCH_LIMIT,\n usersOffset,\n MESSAGE_SEARCH_LIMIT,\n messagesOffset\n )\n .then(function() {\n searchInput.focus();\n usersOffset = usersOffset + USERS_INITIAL_SEARCH_LIMIT;\n messagesOffset = messagesOffset + MESSAGE_SEARCH_LIMIT;\n return;\n })\n .catch(Notification.exception);\n }\n\n data.originalEvent.preventDefault();\n };\n\n CustomEvents.define(searchInput, [CustomEvents.events.enter]);\n CustomEvents.define(header, [CustomEvents.events.activate]);\n CustomEvents.define(body, [CustomEvents.events.activate]);\n\n searchInput.on(CustomEvents.events.enter, searchEventHandler);\n\n header.on(CustomEvents.events.activate, SELECTORS.SEARCH_ACTION, searchEventHandler);\n\n body.on(CustomEvents.events.activate, SELECTORS.LOAD_MORE_MESSAGES, function(e, data) {\n if (searchText !== '') {\n loadMoreMessages(body, loggedInUserId, searchText, MESSAGE_SEARCH_LIMIT, messagesOffset)\n .then(function() {\n messagesOffset = messagesOffset + MESSAGE_SEARCH_LIMIT;\n return;\n })\n .catch(Notification.exception);\n }\n data.originalEvent.preventDefault();\n });\n\n body.on(CustomEvents.events.activate, SELECTORS.LOAD_MORE_USERS, function(e, data) {\n if (searchText !== '') {\n loadMoreUsers(body, loggedInUserId, searchText, USERS_SEARCH_LIMIT, usersOffset)\n .then(function() {\n usersOffset = usersOffset + USERS_SEARCH_LIMIT;\n return;\n })\n .catch(Notification.exception);\n }\n data.originalEvent.preventDefault();\n });\n\n header.on(CustomEvents.events.activate, SELECTORS.CANCEL_SEARCH_BUTTON, function() {\n clearSearchInput(header);\n showEmptyMessage(body);\n showSearchIcon(header);\n hideSearchResults(body);\n hideLoadingIcon(header);\n hideLoadingPlaceholder(body);\n usersOffset = 0;\n messagesOffset = 0;\n });\n\n PubSub.subscribe(Events.CONTACT_ADDED, function(userId) {\n addContact(body, userId);\n });\n\n PubSub.subscribe(Events.CONTACT_REMOVED, function(userId) {\n removeContact(body, userId);\n });\n\n PubSub.subscribe(Events.CONTACT_BLOCKED, function(userId) {\n blockContact(body, userId);\n });\n\n PubSub.subscribe(Events.CONTACT_UNBLOCKED, function(userId) {\n unblockContact(body, userId);\n });\n };\n\n /**\n * Setup the search page.\n *\n * @param {string} namespace The route namespace.\n * @param {Object} header Contacts header container element.\n * @param {Object} body Contacts body container element.\n * @return {Object} jQuery promise\n */\n var show = function(namespace, header, body) {\n if (!body.attr('data-init')) {\n registerEventListeners(header, body);\n body.attr('data-init', true);\n }\n var searchInput = getSearchInput(header);\n searchInput.focus();\n\n return $.Deferred().resolve().promise();\n };\n\n /**\n * String describing this page used for aria-labels.\n *\n * @param {string} namespace The route namespace.\n * @param {Object} header Contacts header container element.\n * @return {Object} jQuery promise\n */\n var description = function(namespace, header) {\n if (typeof header !== 'object') {\n return Str.get_string('messagedrawerviewsearch', 'core_message');\n }\n var searchInput = getSearchInput(header);\n var searchText = searchInput.val().trim();\n return Str.get_string('messagedrawerviewsearch', 'core_message', searchText);\n };\n\n return {\n show: show,\n description: description\n };\n});\n"],"names":["define","$","CustomEvents","Notification","PubSub","Str","Templates","Repository","Events","SELECTORS","TEMPLATES","getLoggedInUserId","body","attr","getEmptyMessageContainer","find","getLoadingIconContainer","header","getLoadingPlaceholder","getSearchIconContainer","getSearchInput","getSearchResultsContainer","getContactsContainer","getNonContactsContainer","hideEmptyMessage","addClass","hideLoadingIcon","hideLoadingPlaceholder","showSearchIcon","removeClass","hideSearchResults","clearAllSearchResults","empty","container","hideNoSearchResults","showAllContactsSearchResults","showContactsSearchResults","showNonContactsSearchResults","showMessagesSearchResults","showLoadMoreUsersButton","showLoadMoreMessagesButton","startLoading","hideSearchIcon","showLoadingIcon","showLoadingPlaceholder","prop","disableSearchInput","stopLoading","showSearchResults","enableSearchInput","hideUsersLoadingIcon","root","button","hideMessagesLoadingIcon","findContact","userId","highlightSearch","content","searchText","regex","RegExp","replace","renderMessages","messages","frompanel","list","render","then","html","append","loadMoreUsers","loggedInUserId","text","limit","offset","loadedAll","showUsersLoadingIcon","searchUsers","results","contacts","noncontacts","length","slice","contactsCount","nonContactsCount","forEach","contact","highlight","fullname","when","renderContacts","nonContacts","renderNonContacts","counts","hideLoadMoreUsersButton","catch","error","loadMoreMessages","showMessagesLoadingIcon","searchMessages","message","lastmessage","count","hideLoadMoreMessagesButton","search","usersLimit","usersOffset","messagesLimit","messagesOffset","userCounts","messagesCount","hideContactsSearchResults","hideNonContactsSearchResults","hideAllContactsSearchResults","hideMessagesSearchResults","showNoSearchResults","registerEventListeners","searchInput","searchEventHandler","e","data","val","trim","focus","exception","originalEvent","preventDefault","events","enter","activate","on","clearSearchInput","showEmptyMessage","subscribe","CONTACT_ADDED","nonContactsContainer","nonContact","userid","remove","contactsContainer","children","addContact","CONTACT_REMOVED","removeContact","CONTACT_BLOCKED","blockContact","CONTACT_UNBLOCKED","unblockContact","show","namespace","Deferred","resolve","promise","description","get_string"],"mappings":"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"}