• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/**
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15import prompt from '@system.prompt';
16
17import HiLog from '../../utils/HiLog';
18import common from '../../data/commonData';
19import ContactsService from '../../service/ContactsService';
20import commonService from '../../service/CommonService'
21import commonCtrl from '../../pages/conversation/common'
22import LooseObject from '../../data/LooseObject'
23import promptAction from '@ohos.promptAction';
24
25const TAG = 'ReceiveController';
26
27export default class ReceiveController {
28    private static sInstance: ReceiveController;
29    commonCtrl = commonCtrl.getInstance();
30    refresh: boolean = false;
31    // Recipient information (selected)
32    selectContacts: Array<any> = [];
33    contacts: Array<any> = [];
34    // Recipient list information (all)
35    contactsTemp: Array<any> = [];
36    // Recipient Content
37    myText: string = '';
38    // true: focus editing status (gray); false: no focus (blue)
39    isInputStatus: boolean = true;
40    // true Show Search List
41    isShowSearch: boolean = true;
42    strSelectContact: string = '';
43    styleTextarea: string = 'select-contact-textarea';
44    hasBlur: boolean = false;
45    // List pagination, number of pages
46    page: number = 0;
47    // List pagination, quantity
48    limit: number = 10;
49    // Total number of contacts
50    totalMessage: number = 0;
51
52    static getInstance() {
53        if (ReceiveController.sInstance == null) {
54            ReceiveController.sInstance = new ReceiveController();
55        }
56        return ReceiveController.sInstance;
57    }
58
59    onInit(call) {
60        HiLog.i(TAG, 'onInit()');
61        this.selectContacts = this.commonCtrl.paramContact.transmitContacts;
62        if (this.selectContacts.length > 0) {
63            let that = this;
64            setTimeout(function () {
65                that.setContactValue(call);
66            }, 200);
67            this.isShowSearch = false;
68            this.setInputStatus(false);
69        }
70        this.requestItem();
71        this.refresh = !this.refresh;
72    }
73
74    onBackPress() {
75        this.InputTextClear();
76        return true;
77    }
78
79    InputTextClear() {
80        this.myText = '';
81        this.setInputStatus(true);
82        this.commonCtrl.paramContact.transmitContacts = [];
83        HiLog.i(TAG,'InputTextClear');
84    }
85
86    requestItem() {
87        let count = this.page * this.limit;
88        if (this.page === 0) {
89            this.page++;
90            this.queryContacts();
91        } else if (count < this.totalMessage && this.contacts.length > (this.page - 1) * this.limit) {
92            // The restriction on Contacts is to prevent multiple refresh requests during initialization.
93            this.page++;
94            this.queryContacts();
95        }
96    }
97
98    queryContacts() {
99        let actionData = {
100            page: this.page,
101            limit: this.limit
102        };
103        // Querying Contacts
104        ContactsService.getInstance().queryContact(actionData, contacts => {
105            if (common.int.SUCCESS == contacts.code) {
106                let response = this.contacts.concat(contacts.response);
107                this.contacts = [];
108                this.contacts = response;
109                this.contactsTemp = this.contacts.slice(0);
110            } else {
111                HiLog.w(TAG, 'queryContacts, fail');
112            }
113        }, null);
114        // Number of statistics
115        ContactsService.getInstance().queryContactSizeByCondition(actionData, res => {
116            if (res.code == common.int.SUCCESS) {
117                this.totalMessage = res.abilityResult;
118            }
119        }, null);
120    }
121
122    searchContacts(textValue, callback) {
123        HiLog.i(TAG, 'searchContacts start');
124        let actionData = {
125            telephone: textValue,
126        };
127        ContactsService.getInstance().queryContactViewByCondition(actionData, res => {
128            if (res.code == common.int.SUCCESS) {
129                this.contacts = res.abilityResult;
130            } else {
131                HiLog.w(TAG, 'searchContacts fail');
132            }
133            callback(res.code);
134        }, null);
135    }
136
137    // Filter search terms to match contacts
138    filterContacts(textValue) {
139        try {
140            this.contacts = this.contactsTemp.filter((contact) => {
141                if (contact.contactName && contact.contactName.toLowerCase().search(textValue) != -1) {
142                    HiLog.i(TAG, 'filterContacts, contactName');
143                    return true;
144                } else if (contact.telephone && contact.telephone.toLowerCase().search(textValue) != -1) {
145                    HiLog.i(TAG, 'filterContacts, telephone');
146                    return true;
147                }
148                return false;
149            });
150        } catch (Error) {
151            HiLog.i(TAG, `error message: ${JSON.stringify(Error)}`);
152        }
153    }
154
155    isPhoneNumber(str) {
156        // Determine whether the value is a number.
157        let reg = /^\d{1,}$/;
158        let pattern = new RegExp(reg);
159        return pattern.test(str);
160    }
161
162    setInputStatus(flag) {
163        this.isInputStatus = flag;
164        if (!flag) {
165            this.strSelectContact = this.setShowContactName();
166        }
167    }
168
169    checkReceive(call) {
170        HiLog.i(TAG, 'checkReceive, isInputStatus: ' + this.isInputStatus);
171        if (this.myText.trim() == common.string.EMPTY_STR) {
172            this.strSelectContact = this.setShowContactName();
173            this.isShowSearch = false;
174            return;
175        }
176        this.hasBlur = true;
177        if (this.isPhoneNumber(this.myText)) {
178            // Get information from the contact list
179            let that = this;
180            let selectContact: LooseObject = {};
181            let hasSelect = false;
182            for (let index in this.contacts) {
183                let contact = this.contacts[index];
184                if (contact.telephone == that.myText) {
185                    selectContact.headImage = 'icon/user_avatar_full_fill.svg';
186                    selectContact.contactName = contact.contactName;
187                    selectContact.telephone = contact.telephone;
188                    selectContact.telephoneFormat = contact.telephone;
189                    selectContact.select = false;
190                    hasSelect = true;
191                    break;
192                }
193            }
194            if (!hasSelect) {
195                selectContact.headImage = common.string.EMPTY_STR;
196                selectContact.contactName = common.string.EMPTY_STR;
197                selectContact.telephone = that.myText;
198                selectContact.telephoneFormat = that.myText;
199                selectContact.select = false;
200            }
201            HiLog.i(TAG, 'checkReceive, isPhoneNumber yes');
202            this.selectContacts.push(selectContact);
203            this.refresh = !this.refresh;
204            this.setInputStatus(false);
205            this.isShowSearch = false;
206            this.setContactValue(call);
207        } else {
208            HiLog.i(TAG, 'checkReceive, isPhoneNumber no');
209            promptAction.showToast({
210                // Invalid Recipient
211                // @ts-ignore
212                message: $r('app.string.invalid_receive', this.myText),
213                duration: 1000,
214            });
215            this.myText = '';
216            this.isShowSearch = true;
217            this.setContactValue(call);
218        }
219    }
220
221    searchChange(text, call) {
222        HiLog.d(TAG, 'searchChange, start');
223        if (this.checkSingle()) {
224            this.setInputStatus(false);
225            this.isShowSearch = false;
226            return;
227        }
228        this.myText = text;
229        if (!this.isInputStatus) {
230            HiLog.w(TAG, 'searchChange, isInputStatus false');
231            return;
232        }
233        this.searchContacts(this.myText, code => {
234            if (code == common.int.SUCCESS && this.myText.trim() != '') {
235                this.setContactValue(call);
236                this.dealSearchData();
237                this.setContactValue(call);
238            } else {
239                this.setContactValue(call);
240            }
241        });
242    }
243
244    dealSearchData() {
245        if (this.myText.trim() == '') {
246            this.contacts = this.contactsTemp.slice(0);
247        } else {
248            let textValue = this.myText.trim().toLowerCase();
249            // Filtering logic
250            this.filterContacts(textValue);
251        }
252    }
253
254    setContactValue(call) {
255        // Send recipient information to the invoked parent component.
256        call({
257            // Select the content of the text box before the contact.
258            contactValue: this.myText,
259            // Selected recipient information
260            selectContacts: this.selectContacts,
261            // Whether the focus is lost
262            hasBlur: this.hasBlur
263        });
264    }
265
266    addContact(index, call) {
267        let curItem = this.contacts[index];
268        if (this.checkSingle()) {
269            return;
270        }
271        if (curItem == undefined) {
272            HiLog.e(TAG, 'addContact contact is null');
273            return;
274        }
275        if (curItem != undefined && curItem.telephone != undefined && curItem.telephone.toString().trim() == '') {
276            prompt.showToast({
277                // Invalid Recipient
278                // @ts-ignore
279                message: $r('app.string.invalid_receive', this.myText),
280                duration: 1000,
281            });
282            return;
283        }
284        this.selectContacts.push(curItem);
285        this.contactsTemp = this.contactsTemp.filter((item) => {
286            if (item.telephone == undefined || curItem.telephone == undefined) {
287                return;
288            }
289            HiLog.w(TAG, 'addContact');
290            return item.telephone != curItem.telephone
291        });
292        this.contacts.splice(index, 1);
293        HiLog.i(TAG, 'addContact, length: ' + this.selectContacts.length);
294        this.myText = '';
295        if (this.selectContacts.length == 1) {
296            this.setInputStatus(false);
297            this.isShowSearch = false;
298            this.setContactValue(call);
299        } else {
300            this.setInputStatus(true);
301            this.isShowSearch = true;
302            this.setContactValue(call);
303        }
304        HiLog.i(TAG, 'addContact, isInputStatus: ' + this.isInputStatus);
305    }
306
307    setShowContactName() {
308        if (this.selectContacts.length == 0) {
309            return '';
310        }
311        let myName = this.selectContacts[0]?.contactName?.trim();
312        if (!myName) {
313            myName = ''
314        }
315        let telephone = this.selectContacts[0]?.telephone
316        if (telephone === undefined || telephone === null) {
317            HiLog.e(TAG, 'setShowContactName fail');
318            return '';
319        }
320        if (!this.isPhoneNumber(telephone)) {
321            myName = telephone.replace(new RegExp(/e|-|#|\*|\./, 'g'), common.string.EMPTY_STR);
322        } else {
323            if (myName == '') {
324                myName = telephone;
325            }
326        }
327        if (this.selectContacts.length >= 2) {
328            // name and other numbers
329            return $r('app.string.and_others', myName, this.selectContacts.length - 1)
330        } else {
331            return myName
332        }
333    }
334
335    myContactFocus() {
336        HiLog.i(TAG, 'myContactFocus, start');
337        this.myText = common.string.EMPTY_STR;
338        this.setInputStatus(true);
339        this.isShowSearch = true;
340    }
341
342    myContactClick() {
343        HiLog.i(TAG, 'myContactClick, start');
344        if (!this.isInputStatus) {
345            this.myText = common.string.EMPTY_STR;
346            this.setInputStatus(true);
347            this.isShowSearch = true;
348            // The TextArea control does not support focus.
349            //      this.$element('receiveTxt').focus({
350            //        focus: true
351            //      });
352        }
353    }
354
355    nameClick(idx, call) {
356        HiLog.i(TAG, 'click-->' + idx);
357        if (this.selectContacts[idx] == null || this.selectContacts[idx] == undefined) {
358            return;
359        }
360        if (this.selectContacts[idx].select && this.selectContacts[idx].select != undefined) {
361            let item = this.selectContacts.splice(idx, 1);
362            // Deleted items are added to the collection to be searched.
363            this.contactsTemp.push(item);
364            if (item[0] != undefined && item[0].telephoneFormat != undefined &&
365            item[0].telephoneFormat.toString().trim() != '') {
366                this.contacts.push(item[0]);
367            }
368            this.refresh = !this.refresh;
369            this.setContactValue(call);
370            return;
371        }
372        for (let element of this.selectContacts) {
373            element.select = false;
374        }
375        this.selectContacts[idx].select = true;
376        this.refresh = !this.refresh;
377    }
378
379    clickToContacts(call) {
380        var actionData: LooseObject = {};
381        actionData.pageFlag = common.contactPage.PAGE_FLAG_SINGLE_CHOOSE;
382        this.jumpToContactForResult(actionData, call);
383    }
384    // Tap a contact's avatar to go to the contact details page.
385    titleBarAvatar(index) {
386        var actionData: LooseObject = {};
387        actionData.phoneNumber = this.contacts[index]?.telephone;
388        actionData.pageFlag = common.contactPage.PAGE_FLAG_CONTACT_DETAILS;
389        this.jumpToContact(actionData);
390    }
391    // Switching to the Contacts app
392    jumpToContact(actionData) {
393        let str = commonService.commonContactParam(actionData);
394        globalThis.mmsContext.startAbility(str).then((data) => {
395        }).catch((error) => {
396            HiLog.i(TAG, 'jumpToContact failed');
397        });
398    }
399    // Switching to the Contacts app
400    async jumpToContactForResult(actionData, call) {
401        let str = commonService.commonContactParam(actionData);
402        var data = await globalThis.mmsContext.startAbilityForResult(str);
403        if (data.resultCode == 0) {
404            this.dealContactParams(data.want.parameters.contactObjects, call);
405        }
406    }
407
408    dealContactParams(contactObjects, call) {
409        this.selectContacts = [];
410        let params = JSON.parse(contactObjects);
411        if (this.checkSingle()) {
412            return;
413        }
414        for (let element of params) {
415            let selectContact: LooseObject = {};
416            selectContact.headImage = 'icon/user_avatar_full_fill.svg';
417            selectContact.contactName = element.contactName;
418            selectContact.telephone = element.telephone;
419            selectContact.telephoneFormat = element.telephone;
420            selectContact.select = false;
421            this.selectContacts.push(selectContact);
422        }
423        if (params.length > 1 && this.checkSingle()) {
424            this.selectContacts = [];
425            return;
426        }
427        if (this.selectContacts.length > 0) {
428            this.deleteRepetitionContacts(this.contacts, this.selectContacts);
429            this.setInputStatus(false);
430            this.isShowSearch = false;
431            this.setContactValue(call);
432        }
433        this.commonCtrl.paramContact.isSelectContact = false;
434        this.commonCtrl.paramContact.isNewRecallMessagesFlag = false;
435    }
436
437    deleteRepetitionContacts(contacts, selectContacts) {
438        let indexs = [];
439        let count = 0;
440        for (let item of contacts) {
441            let telephone = item.telephone;
442            for (let selectContact of selectContacts) {
443                if (telephone == selectContact.telephone) {
444                    indexs.push(count);
445                    break;
446                }
447            }
448            count++;
449        }
450        let selectContactIndexs = [];
451        for (let i = 0; i < selectContacts.length; i++) {
452            let telephone = selectContacts[i].telephone;
453            for (let j = i + 1; j < selectContacts.length; j++) {
454                if (telephone == selectContacts[j].telephone) {
455                    selectContactIndexs.push(i);
456                    break;
457                }
458            }
459        }
460        if (indexs.length > 0) {
461            for (let index of indexs) {
462                contacts.splice(index, 1);
463            }
464        }
465        if (selectContactIndexs.length > 0) {
466            for (let index of selectContactIndexs) {
467                selectContacts.splice(index, 1);
468            }
469        }
470    }
471
472    // Currently, only one recipient is supported. You can enter only one recipient first.
473    checkSingle() {
474        if (this.selectContacts.length > 0) {
475            prompt.showToast({
476                // Invalid Recipient
477                // @ts-ignore
478                message: '只支持单个收件人',
479                duration: 1000,
480            });
481            return true;
482        } else {
483            return false;
484        }
485    }
486}