// (C) Copyright 2015 Martin Dougiamas // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. import { Component } from '@angular/core'; import { NavParams } from 'ionic-angular'; import { TranslateService } from '@ngx-translate/core'; import { CoreSitesProvider } from '@providers/sites'; import { AddonMessagesProvider } from '../../providers/messages'; import { CoreDomUtilsProvider } from '@providers/utils/dom'; import { CoreUtilsProvider } from '@providers/utils/utils'; import { CoreAppProvider } from '@providers/app'; import { CoreEventsProvider } from '@providers/events'; /** * Component that displays the list of contacts. */ @Component({ selector: 'addon-messages-contacts', templateUrl: 'contacts.html', }) export class AddonMessagesContactsComponent { protected currentUserId: number; protected searchingMessages: string; protected loadingMessages: string; protected siteId: string; protected noSearchTypes = ['online', 'offline', 'blocked', 'strangers']; loaded = false; discussionUserId: number; contactTypes = this.noSearchTypes; searchType = 'search'; loadingMessage = ''; hasContacts = false; contacts = { search: [] }; searchString = ''; constructor(sitesProvider: CoreSitesProvider, translate: TranslateService, private appProvider: CoreAppProvider, private messagesProvider: AddonMessagesProvider, private domUtils: CoreDomUtilsProvider, navParams: NavParams, private eventsProvider: CoreEventsProvider) { this.currentUserId = sitesProvider.getCurrentSiteUserId(); this.siteId = sitesProvider.getCurrentSiteId(); this.searchingMessages = translate.instant('core.searching'); this.loadingMessages = translate.instant('core.loading'); this.loadingMessage = this.loadingMessages; this.discussionUserId = navParams.get('discussionUserId') || false; } /** * Component loaded. */ ngOnInit(): void { if (this.discussionUserId) { // There is a discussion to load, open the discussion in a new state. this.gotoDiscussion(this.discussionUserId); } this.fetchData().then(() => { if (!this.discussionUserId && this.hasContacts) { let contact; for (const x in this.contacts) { if (this.contacts[x].length > 0) { contact = this.contacts[x][0]; break; } } if (contact) { // Take first and load it. this.gotoDiscussion(contact.id, true); } } }).finally(() => { this.loaded = true; }); } /** * Refresh the data. * * @param {any} [refresher] Refresher. * @return {Promise} Promise resolved when done. */ refreshData(refresher?: any): Promise { let promise; if (this.searchString) { // User has searched, update the search. promise = this.performSearch(this.searchString); } else { // Update contacts. promise = this.messagesProvider.invalidateAllContactsCache(this.currentUserId).then(() => { return this.fetchData(); }); } return promise.finally(() => { refresher.complete(); }); } /** * Fetch contacts. * * @return {Promise} Promise resolved when done. */ protected fetchData(): Promise { this.loadingMessage = this.loadingMessages; return this.messagesProvider.getAllContacts().then((contacts) => { for (const x in contacts) { if (contacts[x].length > 0) { this.contacts[x] = this.sortUsers(contacts[x]); } else { this.contacts[x] = []; } } this.clearSearch(); }).catch((error) => { this.domUtils.showErrorModalDefault(error, 'addon.messages.errorwhileretrievingcontacts', true); }); } /** * Sort user list by fullname * @param {any[]} list List to sort. * @return {any[]} Sorted list. */ protected sortUsers(list: any[]): any[] { return list.sort((a, b) => { const compareA = a.fullname.toLowerCase(), compareB = b.fullname.toLowerCase(); return compareA.localeCompare(compareB); }); } /** * Clear search and show all contacts again. */ clearSearch(): void { this.searchString = ''; // Reset searched string. this.contactTypes = this.noSearchTypes; this.hasContacts = false; for (const x in this.contacts) { if (this.contacts[x].length > 0) { this.hasContacts = true; return; } } } /** * Search users from the UI. * * @param {string} query Text to search for. * @return {Promise} Resolved when done. */ search(query: string): Promise { this.appProvider.closeKeyboard(); this.loaded = false; this.loadingMessage = this.searchingMessages; return this.performSearch(query).finally(() => { this.loaded = true; }); } /** * Perform the search of users. * * @param {string} query Text to search for. * @return {Promise} Resolved when done. */ protected performSearch(query: string): Promise { return this.messagesProvider.searchContacts(query).then((result) => { this.hasContacts = result.length > 0; this.searchString = query; this.contactTypes = ['search']; this.contacts['search'] = this.sortUsers(result); }).catch((error) => { this.domUtils.showErrorModalDefault(error, 'addon.messages.errorwhileretrievingcontacts', true); }); } /** * Navigate to a particular discussion. * * @param {number} discussionUserId Discussion Id to load. * @param {boolean} [onlyWithSplitView=false] Only go to Discussion if split view is on. */ gotoDiscussion(discussionUserId: number, onlyWithSplitView: boolean = false): void { this.discussionUserId = discussionUserId; const params = { discussion: discussionUserId, onlyWithSplitView: onlyWithSplitView }; this.eventsProvider.trigger(AddonMessagesProvider.SPLIT_VIEW_LOAD_EVENT, params, this.siteId); } }