• 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.$watch("paramContact", "onPropertyChange");
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            prompt.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            //      this.$element("receiveTxt").focus({
248            //        focus: true
249            //      });
250        } else {
251            let textValue = this.myText.trim().toLowerCase();
252            // Filtering logic
253            this.filterContacts(textValue);
254        }
255    }
256
257    setContactValue(call) {
258        // Send recipient information to the invoked parent component.
259        call({
260            // Select the content of the text box before the contact.
261            contactValue: this.myText,
262            // Selected recipient information
263            selectContacts: this.selectContacts,
264            // Whether the focus is lost
265            hasBlur: this.hasBlur
266        });
267    }
268
269    addContact(index, call) {
270        let curItem = this.contacts[index];
271        if (this.checkSingle()) {
272            return;
273        }
274        if (curItem != undefined && curItem.telephone != undefined && curItem.telephone.toString().trim() == "") {
275            prompt.showToast({
276                // Invalid Recipient
277                // @ts-ignore
278                message: $r("app.string.invalid_receive", this.myText),
279                duration: 1000,
280            });
281            return;
282        }
283        this.selectContacts.push(curItem);
284        this.contactsTemp = this.contactsTemp.filter((item) => {
285            if (item.telephone == undefined || curItem.telephone == undefined) {
286                return;
287            }
288            HiLog.w(TAG, "addContact");
289            return item.telephone != curItem.telephone
290        });
291        this.contacts.splice(index, 1);
292        HiLog.i(TAG, "addContact, length: " + this.selectContacts.length);
293        this.myText = '';
294        if (this.selectContacts.length == 1) {
295            this.setInputStatus(false);
296            this.isShowSearch = false;
297            this.setContactValue(call);
298        } else {
299            this.setInputStatus(true);
300            this.isShowSearch = true;
301            this.setContactValue(call);
302        }
303        HiLog.i(TAG, "addContact, isInputStatus: " + this.isInputStatus);
304    }
305
306    setShowContactName() {
307        if (this.selectContacts.length == 0) {
308            return '';
309        }
310        let myName = this.selectContacts[0]?.contactName?.trim();
311        if (!myName) {
312            myName = ""
313        }
314        let telephone = this.selectContacts[0]?.telephone
315        if (telephone === undefined || telephone === null) {
316            HiLog.e(TAG, "setShowContactName fail");
317            return '';
318        }
319        if (!this.isPhoneNumber(telephone)) {
320            myName = telephone.replace(new RegExp(/e|-|#|\*|\./, "g"), common.string.EMPTY_STR);
321        } else {
322            if (myName == "") {
323                myName = telephone;
324            }
325        }
326        if (this.selectContacts.length >= 2) {
327            // name and other numbers
328            return $r("app.string.and_others", myName, this.selectContacts.length - 1)
329        } else {
330            return myName
331        }
332    }
333
334    myContactFocus() {
335        HiLog.i(TAG, "myContactFocus, start");
336        this.myText = common.string.EMPTY_STR;
337        this.setInputStatus(true);
338        this.isShowSearch = true;
339    }
340
341    myContactClick() {
342        HiLog.i(TAG, "myContactClick, start");
343        if (!this.isInputStatus) {
344            this.myText = common.string.EMPTY_STR;
345            this.setInputStatus(true);
346            this.isShowSearch = true;
347            // The TextArea control does not support focus.
348            //      this.$element("receiveTxt").focus({
349            //        focus: true
350            //      });
351        }
352    }
353
354    nameClick(idx, call) {
355        HiLog.i(TAG, "click-->" + idx)
356        if (this.selectContacts[idx] == null || this.selectContacts[idx] == undefined) {
357            return;
358        }
359        if (this.selectContacts[idx].select) {
360            let item = this.selectContacts.splice(idx, 1);
361            // Deleted items are added to the collection to be searched.
362            this.contactsTemp.push(item);
363            if (item[0] != undefined && item[0].telephoneFormat != undefined &&
364            item[0].telephoneFormat.toString().trim() != "") {
365                this.contacts.push(item[0]);
366            }
367            this.refresh = !this.refresh;
368            this.setContactValue(call);
369            return;
370        }
371        for (let element of this.selectContacts) {
372            element.select = false;
373        }
374        this.selectContacts[idx].select = true;
375        this.refresh = !this.refresh;
376    }
377
378    clickToContacts(call) {
379        var actionData: LooseObject = {};
380        actionData.pageFlag = common.contactPage.PAGE_FLAG_SINGLE_CHOOSE;
381        this.jumpToContactForResult(actionData, call);
382    }
383    // Tap a contact's avatar to go to the contact details page.
384    titleBarAvatar(index) {
385        var actionData: LooseObject = {};
386        actionData.phoneNumber = this.contacts[index]?.telephone;
387        actionData.pageFlag = common.contactPage.PAGE_FLAG_CONTACT_DETAILS;
388        this.jumpToContact(actionData);
389    }
390    // Switching to the Contacts app
391    jumpToContact(actionData) {
392        let str = commonService.commonContactParam(actionData);
393        globalThis.mmsContext.startAbility(str).then((data) => {
394        }).catch((error) => {
395            HiLog.i(TAG, "jumpToContact failed");
396        });
397    }
398    // Switching to the Contacts app
399    async jumpToContactForResult(actionData, call) {
400        let str = commonService.commonContactParam(actionData);
401        var data = await globalThis.mmsContext.startAbilityForResult(str);
402        if (data.resultCode == 0) {
403            this.dealContactParams(data.want.parameters.contactObjects, call);
404        }
405    }
406
407    dealContactParams(contactObjects, call) {
408        this.selectContacts = [];
409        let params = JSON.parse(contactObjects);
410        if (this.checkSingle()) {
411            return;
412        }
413        for (let element of params) {
414            let selectContact: LooseObject = {};
415            selectContact.headImage = "icon/user_avatar_full_fill.svg";
416            selectContact.contactName = element.contactName;
417            selectContact.telephone = element.telephone;
418            selectContact.telephoneFormat = element.telephone;
419            selectContact.select = false;
420            this.selectContacts.push(selectContact);
421        }
422        if (params.length > 1 && this.checkSingle()) {
423            this.selectContacts = [];
424            return;
425        }
426        if (this.selectContacts.length > 0) {
427            this.deleteRepetitionContacts(this.contacts, this.selectContacts);
428            this.setInputStatus(false);
429            this.isShowSearch = false;
430            this.setContactValue(call);
431        }
432        this.commonCtrl.paramContact.isSelectContact = false;
433        this.commonCtrl.paramContact.isNewRecallMessagesFlag = false;
434    }
435
436    deleteRepetitionContacts(contacts, selectContacts) {
437        let indexs = [];
438        let count = 0;
439        for (let item of contacts) {
440            let telephone = item.telephone;
441            for (let selectContact of selectContacts) {
442                if (telephone == selectContact.telephone) {
443                    indexs.push(count);
444                    break;
445                }
446            }
447            count++;
448        }
449        let selectContactIndexs = [];
450        for (let i = 0; i < selectContacts.length; i++) {
451            let telephone = selectContacts[i].telephone;
452            for (let j = i + 1; j < selectContacts.length; j++) {
453                if (telephone == selectContacts[j].telephone) {
454                    selectContactIndexs.push(i);
455                    break;
456                }
457            }
458        }
459        if (indexs.length > 0) {
460            for (let index of indexs) {
461                contacts.splice(index, 1);
462            }
463        }
464        if (selectContactIndexs.length > 0) {
465            for (let index of selectContactIndexs) {
466                selectContacts.splice(index, 1);
467            }
468        }
469    }
470
471    // Currently, only one recipient is supported. You can enter only one recipient first.
472    checkSingle() {
473        if (this.selectContacts.length > 0) {
474            prompt.showToast({
475                // Invalid Recipient
476                // @ts-ignore
477                message: "只支持单个收件人",
478                duration: 1000,
479            });
480            return true;
481        } else {
482            return false;
483        }
484    }
485}