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