• 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 router from '@system.router';
16import commonEvent from '@ohos.commonEventManager';
17import dataShare from '@ohos.data.dataShare';
18
19import common from '../../data/commonData'
20import DateUtil from '../../utils/DateUtil';
21import LooseObject from '../../data/LooseObject';
22import ConversationListService from '../../service/ConversationListService';
23import ConversationService from '../../service/ConversationService';
24import HiLog from '../../utils/HiLog';
25import SettingService from '../../service/SettingService'
26import commonService from '../../service/CommonService';
27import NotificationService from '../../service/NotificationService';
28import ConversationListDataSource from '../../model/ConversationListDataSource';
29import AvatarColor from '../../model/common/AvatarColor';
30import StringUtil from '../../utils/StringUtil';
31
32let ConversationCtrl;
33
34const TAG = 'ConversationListController';
35
36export default class ConversationListController {
37    // Determine whether to perform initialization. (To avoid the onShow time sequence problem immediately after the
38    // index is started.)
39    private dataShareHelper;
40    isInited: boolean = false;
41
42    commonEventData: any = null;
43    svgDelete: string = '';
44    strCheckBoxSelectTip: Resource;
45    strMsgDeleteDialogTip: Resource = null;
46    // Total number of SMs
47    total: number = 0;
48    // Total number of notifications.
49    totalOfInfo: number = 0;
50    // Total number of unread messages.
51    unreadTotal: number = 0;
52    // Total number of unread notifications
53    unreadTotalOfInfo: number = 0;
54    // Number of selected sessions
55    conversationSelectedNumber: number = 0;
56    // Indicates whether the multi-select state is selected.
57    isMultipleSelectState: boolean = false;
58    // Indicates whether the session list is selected.
59    isConversationCheckAll: boolean = false;
60    // Value entered in the search box on the information list page
61    inputValueOfSearch: string = '';
62    inputValueOfSearchTemp: string = '';
63    // Mark as read is hidden in the row where the notification is located. When there is unread information,
64    // you can swipe left to view this icon.
65    markAllAsReadForInfo: boolean = false;
66    // Mark as read
67    showMarkAllAsRead: boolean = false;
68    // Delete. In each individual message line, swipe left on the screen.
69    showDelete: boolean = false;
70    // Indicates whether to lock. The default value is false. No.
71    hasLockMsg: boolean = false;
72    isSelectLockMsg: boolean = false;
73    // Dynamically setting the height of the deleted pop-up window
74    dialogHeight: string = '';
75    // Data in the notification message
76    messageListForInfo: Array<any> = [];
77    // If the notification integration switch is turned on, the information is not a notification.
78    // If the notification integration switch is not turned on, the information is all data.
79    messageList: Array<any> = [];
80    // List of search results
81    searchResultList: LooseObject = {
82        'sessionList': [],
83        'contentList': []
84    };
85    // Search Results Queue
86    searchResultListQueue: Array<any> = [];
87    // Search Text Queue
88    searchTextQueue: Array<any> = [];
89    // Queue start flag bit
90    queueFlag: boolean = false;
91    // Queue timer start flag bit
92    setTimeOutQueueFlag: boolean = false;
93    // Number of search results
94    countOfSearchResult: number = 0;
95    // Indicates whether to perform redirection to avoid repeated redirection.
96    isJumping: boolean = false;
97    // Indicates whether to enable the notification integration switch. This switch is in the Settings area.
98    hasAggregate: boolean = false;
99    // Display contact avatar
100    isShowContactHeadIcon: boolean = true;
101    // Indicates whether to display the search return button. By default, the button is not displayed.
102    isShowSearchBack: boolean = false;
103    isSearchFocusable: boolean = false;
104    // The transparent color of the mask is displayed during search.
105    isSearchCoverage: boolean = false;
106    // Display Query All Information
107    isSearchStatus: boolean = true;
108    // Whether to display session search
109    isSearchConversation: boolean = false;
110    // Show Spacer Lines
111    isSearchInterval: boolean = false;
112    // Display Single Information Search
113    isSearchSms: boolean = false;
114    // Show Search Status
115    showSearchStatus: Resource;
116    // Indicates whether to display the button for creating an SMS message.
117    isNewSms: boolean = true;
118    conversationName: string = '';
119    // Check whether a common message (non-notification message) exists.
120    hasNoOrdinaryMsg: boolean = false;
121    // Check whether notification information exists.
122    hasInfoMsg: boolean = false;
123    // Update the UI.
124    flushTranslate: boolean = true;
125    // Length of the operation button
126    operateBtnW: number = 145;
127    // Data index of the current touch
128    itemTouchedIdx: number = -1;
129    // Left margin of notification message
130    infoLeft: number = 0;
131    // List pagination, number of pages
132    page: number = 0;
133    // List pagination, quantity
134    limit: number = 0;
135    reg: RegExp = /^[\u4e00-\u9fa5_a-zA-Z]+$/;
136    delItem: number;
137    // conversation list adapters
138    conversationListDataSource: ConversationListDataSource = new ConversationListDataSource();
139
140    static getInstance() {
141        if (ConversationCtrl == null) {
142            ConversationCtrl = new ConversationListController();
143        }
144        return ConversationCtrl;
145    }
146
147
148    onInit() {
149        HiLog.i(TAG, 'onInit');
150        this.isInited = true;
151        this.svgDelete = 'icon/ic_public_delete.svg';
152        this.strCheckBoxSelectTip = $r('app.string.msg_select_all');
153        this.strMsgDeleteDialogTip = $r('app.string.msg_delete_dialog_tip2', this.conversationSelectedNumber);
154        this.showSearchStatus = $r('app.string.noMessages');
155    }
156
157    private async getDataAbilityHelper(context?) {
158        if (this.dataShareHelper == undefined) {
159            this.dataShareHelper = await dataShare.createDataShareHelper(context ? context : globalThis.mmsContext,
160            common.string.URI_ROW_CONTACTS);
161        }
162        return this.dataShareHelper;
163    }
164
165    registerDataChangeObserver(callback, context?) {
166        let contactDataUri: string = common.string.URI_ROW_CONTACTS + common.string.CONTACT_DATA_URI;
167        this.getDataAbilityHelper(context).then((dataAbilityHelper) => {
168            if (dataAbilityHelper) {
169                dataAbilityHelper.on('dataChange', contactDataUri, callback);
170            }
171        }).catch(error => {
172            HiLog.w(TAG, 'error:%s' + JSON.stringify(error.message));
173        });
174    }
175
176    unregisterDataChangeObserver(callback, context?) {
177        let contactDataUri: string = common.string.URI_ROW_CONTACTS + common.string.CONTACT_DATA_URI;
178        this.getDataAbilityHelper(context).then((dataAbilityHelper) => {
179            if (dataAbilityHelper) {
180                dataAbilityHelper.off('dataChange', contactDataUri, callback);
181            }
182        }).catch(error => {
183            HiLog.w(TAG, 'error:%s' + JSON.stringify(error.message));
184        });
185    }
186
187    onShow() {
188        HiLog.i(TAG, 'onShow');
189        if (!this.isInited) {
190            HiLog.w(TAG, 'is not init');
191            return;
192        }
193        this.subscribe();
194        this.isJumping = false;
195        this.getSettingFlagForConvListPage();
196        this.statisticalData();
197        if (globalThis.needToUpdate && this.page == 0) {
198            this.messageList = [];
199            this.requestItem();
200        }
201    }
202
203    onDestroy() {
204        HiLog.i(TAG, 'onDestroy');
205        this.isInited = false;
206    }
207
208    onHide() {
209        HiLog.i(TAG, 'onHide');
210        this.unSubscribe();
211    }
212
213    // Touch and hold a list to display the selection and deletion functions.
214    conversationLongPress(index) {
215        // Check whether the left slide button exists. If yes, the button cannot be clicked.
216        if (this.messageList[index].isDelShow) {
217            return;
218        }
219        // Touch and hold a list to display the selection and deletion functions.
220        HiLog.i(TAG, 'conversationLongPress, index: ' + index);
221        if (this.isMultipleSelectState) {
222            this.messageList[index].isCbChecked = !this.messageList[index].isCbChecked;
223        } else {
224            this.isMultipleSelectState = true;
225            this.messageList[index].isCbChecked = true;
226        }
227        this.setConversationCheckAll(common.int.CHECKBOX_SELECT_UNKNOWN);
228    }
229
230    setConversationCheckAll(selectType) {
231        // Check whether all items are selected.
232        if (!this.isMultipleSelectState) {
233            return;
234        }
235        if (selectType == common.int.CHECKBOX_SELECT_ALL) {
236            this.conversationSelectedNumber = this.messageList.length;
237            this.isConversationCheckAll = true;
238        } else if (selectType == common.int.CHECKBOX_SELECT_NONE) {
239            this.conversationSelectedNumber = common.int.MESSAGE_CODE_ZERO;
240            this.isConversationCheckAll = false;
241        } else {
242            // The default value is CHECKBOX_SELECT_UNKNOWN. Check whether there is any unselected item.
243            this.isConversationCheckAll = true;
244            this.conversationSelectedNumber = 0;
245            this.messageList.forEach((element, index, array) => {
246                if (element.isCbChecked) {
247                    this.conversationSelectedNumber++;
248                } else if (this.isConversationCheckAll) {
249                    this.isConversationCheckAll = false;
250                }
251            })
252            this.conversationListDataSource.refresh(this.messageList);
253        }
254        if (this.isConversationCheckAll) {
255            // Select All Status
256            this.strCheckBoxSelectTip = $r('app.string.msg_deselect_all');
257        } else {
258            // Non-Select All Status
259            this.strCheckBoxSelectTip = $r('app.string.msg_select_all');
260        }
261    }
262
263    backSearch() {
264        this.isShowSearchBack = false;
265        this.isSearchCoverage = false;
266        //  this.$element('searchBox').focus({
267        //    focus: false
268        //  });
269        this.isSearchFocusable = false
270        this.inputValueOfSearch = common.string.EMPTY_STR;
271        this.isSearchStatus = true;
272        this.isNewSms = true;
273        this.searchResultList.sessionList = [];
274        this.searchResultList.contentList = [];
275    }
276
277    // Reset touch event, which is used to reset an item that has been moved by sliding left
278    // when other buttons are pressed.
279    resetTouch() {
280        if (this.itemTouchedIdx !== -1) {
281            let itemTouched = this.messageList[this.itemTouchedIdx];
282            if (itemTouched == undefined) {
283                return false;
284            }
285            if (itemTouched.isDelShow) {
286                itemTouched.isDelShow = false;
287                this.setListItemTransX(0);
288                return true;
289            }
290        } else if (this.showMarkAllAsRead) {
291            this.showMarkAllAsRead = false;
292            this.setInfoItemTransX(0);
293            return true;
294        }
295        return false;
296    }
297
298    // Touch event for information list
299    touchStart(event: GestureEvent, index: number) {
300        if (this.isMultipleSelectState) {
301            return;
302        }
303        if (this.showMarkAllAsRead) {
304            // If the last touch is a notification item, the notification item will be reset.
305                  this.setInfoItemTransX(0);
306                  setTimeout(() => {
307                    this.showMarkAllAsRead = false;
308                  }, 200);
309        } else {
310            // Check whether the current touch item is the same as that of a touch item.
311            // If not, reset the previous touch item.
312            if (this.itemTouchedIdx !== -1 && index !== this.itemTouchedIdx) {
313                let itemTouched = this.messageList[this.itemTouchedIdx];
314                if (itemTouched != undefined && itemTouched != null && itemTouched.isDelShow) {
315                    this.setListItemTransX(0);
316                    itemTouched.isDelShow = false;
317                }
318            }
319        }
320        this.itemTouchedIdx = index;
321        let item = this.messageList[this.itemTouchedIdx];
322        if (item == null || item == undefined) {
323            return;
324        }
325        if (item.countOfUnread > 0) {
326            this.operateBtnW = common.int.OPERATE_UNREAD_WIDTH;
327        } else {
328            this.operateBtnW = common.int.OPERATE_DELETE_WIDTH;
329        }
330    }
331
332    touchMove(event: GestureEvent, index: number) {
333        if (this.isMultipleSelectState) {
334            return;
335        }
336        // offsetX indicates the offset. The value range is [-operateBtnW, 0].
337        let offsetX = event.offsetX;
338        // If the displacement is less than 2, there is no sliding.
339        if (Math.abs(offsetX) <= 2) {
340            return;
341        }
342        let item = this.messageList[this.itemTouchedIdx];
343        let transX = offsetX;
344        if (item.isDelShow) {
345            if (event.offsetX - this.operateBtnW <= 0) {
346                transX = event.offsetX - this.operateBtnW
347            } else {
348                // Slide right to close
349                transX = 0
350            }
351        } else {
352            if (event.offsetX + this.operateBtnW >= 0) {
353                transX = event.offsetX
354            } else {
355                // Slide left to maximum width
356                transX = 0 - this.operateBtnW;
357            }
358        }
359        this.setListItemTransX(transX);
360    }
361
362    touchEnd(event: GestureEvent, index: number) {
363        if (this.isMultipleSelectState) {
364            return;
365        }
366        // offsetX indicates the offset. The value range is [-operateBtnW, 0].
367        let offsetX = event.offsetX;
368        let item = this.messageList[this.itemTouchedIdx];
369        if (offsetX + (this.operateBtnW / 2) >= 0) {
370            this.setListItemTransX(0);
371            item.isDelShow = false;
372        } else {
373            this.setListItemTransX(0 - this.operateBtnW);
374            item.isDelShow = true;
375        }
376    }
377
378    setListItemTransX(transX) {
379        let item = this.messageList[this.itemTouchedIdx];
380        if (item) {
381            if (transX <= 0) {
382                item.itemLeft = transX;
383            } else {
384                item.itemLeft = 0;
385            }
386        }
387        // Used to refresh the interface.
388        this.flushTranslate = !this.flushTranslate;
389    }
390
391    setInfoItemTransX(disX) {
392        if (disX >= 0) {
393            this.infoLeft = -disX;
394        } else {
395            this.infoLeft = -this.operateBtnW - disX;
396        }
397    }
398
399    clickConversationCheckAll() {
400        // Select All/Deselect All
401        if (this.isConversationCheckAll) {
402            for (let element of this.messageList) {
403                element.isCbChecked = false;
404            }
405            this.setConversationCheckAll(common.int.CHECKBOX_SELECT_NONE);
406        } else {
407            // Not Select All --> Select All
408            for (let element of this.messageList) {
409                element.isCbChecked = true;
410            }
411            this.setConversationCheckAll(common.int.CHECKBOX_SELECT_ALL);
412        }
413        this.conversationListDataSource.notifyDataReload();
414    }
415
416    clickConversationDelete() {
417        // Button Delete
418        if (this.conversationSelectedNumber == common.int.MESSAGE_CODE_ZERO) {
419            return;
420        }
421        // Delete a record.
422        if (this.conversationSelectedNumber == common.int.MESSAGE_CODE_ONE) {
423            this.strMsgDeleteDialogTip = $r('app.string.msg_delete_dialog_tip1');
424        } else if (this.conversationSelectedNumber == this.messageList.length) {
425            // Delete All
426            this.strMsgDeleteDialogTip = $r('app.string.msg_delete_dialog_tip3');
427        } else {
428            // Delete multiple records.
429            this.strMsgDeleteDialogTip = $r('app.string.msg_delete_dialog_tip2', this.conversationSelectedNumber);
430        }
431        // Locked or not
432        this.hasLockMsg = this.judgehasLockMsg()
433    }
434
435    judgehasLockMsg() {
436        let hasLockMsg = false;
437        for (let element of this.messageList) {
438            if (element.isCbChecked && element.isLock) {
439                hasLockMsg = true;
440                break;
441            }
442        }
443        return hasLockMsg;
444    }
445
446    onBackPress() {
447        HiLog.i(TAG, 'onBackPress');
448        // Key returned by the system. The value true indicates interception.
449        if (this.isMultipleSelectState) {
450            for (let element of this.messageList) {
451                element.isCbChecked = false;
452            }
453            this.isMultipleSelectState = false;
454            return true;
455        }
456        if (!this.isSearchStatus) {
457            this.backSearch();
458            return true;
459        }
460        return false;
461    }
462
463    deleteDialogConfirm() {
464        this.setDelShow();
465        let mmsList: Array<LooseObject> = [];
466        let threadIds: Array<number> = [];
467        for (let element of this.messageList) {
468            if (element.isCbChecked) {
469                threadIds.push(element.threadId);
470            } else {
471                mmsList.push(element);
472            }
473        }
474        this.isMultipleSelectState = false;
475        this.isSelectLockMsg = false;
476        this.messageList = mmsList;
477        this.conversationListDataSource.refresh(this.messageList);
478        this.total = this.messageList.length;
479        this.hasNoOrdinaryMsg = this.total == 0 ? true : false;
480
481        let actionData: LooseObject = {};
482        actionData.threadIds = threadIds;
483        actionData.hasRead = common.is_read.UN_READ;
484        NotificationService.getInstance().cancelMessageNotify(actionData);
485        NotificationService.getInstance().updateBadgeNumber();
486        actionData.hasRead = null;
487        ConversationListService.getInstance().deleteMessageById(actionData, null, null);
488    }
489
490    deleteDialogCancel() {
491        if (!this.isMultipleSelectState) {
492            this.messageList[this.delItem].isCbChecked = false;
493        }
494        // Cancel Ejection
495        if (this.isSelectLockMsg) {
496            this.isSelectLockMsg = false;
497        }
498    }
499
500    setDelShow() {
501        if (this.itemTouchedIdx >= 0) {
502            let item = this.messageList[this.itemTouchedIdx];
503            this.setListItemTransX(0);
504            item.isDelShow = false;
505        }
506    }
507
508    clickToMarkAllAsRead() {
509        let threadIds: Array<number> = [];
510        for (let mms of this.messageList) {
511            if (mms.countOfUnread > common.int.MESSAGE_CODE_ZERO) {
512                threadIds.push(mms.threadId);
513            }
514        }
515        let actionData: LooseObject = {};
516        NotificationService.getInstance().setBadgeNumber(0);
517        actionData.threadIds = threadIds;
518        actionData.hasRead = common.is_read.UN_READ;
519        NotificationService.getInstance().cancelMessageNotify(actionData);
520        ConversationListService.getInstance().markAllToRead(actionData);
521        this.unreadTotalOfInfo = 0;
522        this.unreadTotal = 0;
523        let tempMsgList: Array<LooseObject> = this.messageList;
524        for (let msg of tempMsgList) {
525            if (threadIds.indexOf(msg.threadId) != -1) {
526                msg.countOfUnread = common.int.MESSAGE_CODE_ZERO;
527            }
528        }
529        this.messageList = tempMsgList;
530        this.conversationListDataSource.refresh(this.messageList);
531    }
532
533    jumpToSettingsPage() {
534        router.push({
535            uri: 'pages/settings/settings',
536            params: {
537                pageFlag: 'settingsDetail',
538            }
539        });
540    }
541
542    subscribe() {
543        let events = [common.string.RECEIVE_TRANSMIT_EVENT]
544        let commonEventSubscribeInfo = {
545            events: events
546        };
547        commonEvent.createSubscriber(commonEventSubscribeInfo, this.createSubscriberCallBack.bind(this));
548
549    }
550
551    subscriberCallBack(err, data) {
552        this.page = 0;
553        this.messageList = [];
554        this.requestItem();
555        // Collecting Unread Information
556        this.statisticalData();
557    }
558
559    // Unsubscribe
560    unSubscribe() {
561        HiLog.i(TAG, 'unSubscribe');
562        if (this.commonEventData != null) {
563            commonEvent.unsubscribe(this.commonEventData, () => {
564                HiLog.i(TAG, 'unSubscribe, success');
565            });
566        }
567    }
568
569    createSubscriberCallBack(err, data) {
570        this.commonEventData = data;
571        // Received subscription
572        commonEvent.subscribe(this.commonEventData, this.subscriberCallBack.bind(this));
573    }
574
575    // statistical data
576    statisticalData() {
577        let that = this;
578        ConversationListService.getInstance().statisticalData(result => {
579            if (result.code == common.int.SUCCESS) {
580                // Total number of lists
581                that.unreadTotal = result.response.totalListCount;
582                // Unreading of notification messages
583                that.unreadTotalOfInfo = result.response.unreadTotalOfInfo;
584                NotificationService.getInstance().setBadgeNumber(Number(that.unreadTotal));
585            } else {
586                HiLog.w(TAG, 'statisticalData, failed');
587            }
588        }, null);
589    }
590
591    // Obtains the switch value for integrating notification information and displaying contact avatars.
592    getSettingFlagForConvListPage() {
593        let that = this;
594        let result = SettingService.getSettingFlagForConvListPage();
595        if (result) {
596            that.hasAggregate = result.hasAggregate;
597            that.isShowContactHeadIcon = result.isShowContactHeadIcon;
598        }
599    }
600
601    // Obtaining List Data in Pagination Mode
602    requestItem() {
603        if (this.page === 0) {
604            this.page++;
605            this.queryAllMessages();
606        } else {
607            HiLog.i(TAG, 'isLoading');
608        }
609    }
610
611    // The notification page is displayed.
612    clickToInfoMessages(hasAggregate, hasInfoMsg, isSearchStatus) {
613        if (this.resetTouch()) {
614            return;
615        }
616        if (this.isMultipleSelectState) {
617            return;
618        }
619        router.push({
620            uri: 'pages/infomsg/InfoMsg'
621        })
622    }
623
624    // Tap the avatar to go to the contact details page or recipient list page.
625    clickToGroupDetail(index) {
626        if (this.isJumping) {
627            return;
628        }
629        this.isJumping = true;
630        // Determine whether to redirect to the contact details page or to the list page of multiple recipients.
631        var contactsNum = this.messageList[index]?.contactsNum;
632        var telephone = this.messageList[index]?.telephone;
633        if (contactsNum == common.int.MESSAGE_CODE_ONE) {
634            var actionData = {
635                phoneNumber: telephone,
636                pageFlag: common.contactPage.PAGE_FLAG_CONTACT_DETAILS
637            };
638            this.jumpToContact(actionData);
639        } else {
640            let threadId = this.messageList[index]?.threadId;
641            let contactsNum = this.messageList[index]?.contactsNum;
642            this.jumpToGroupDetail(threadId, contactsNum);
643        }
644    }
645
646    // Switching to the Contacts app
647    jumpToContact(actionData) {
648        let str = commonService.commonContactParam(actionData);
649        globalThis.mmsContext.startAbility(str).then((data) => {
650            HiLog.i(TAG, 'jumpToContact, startAbility success');
651        }).catch((error) => {
652            HiLog.e(TAG, 'jumpToContact, failed Cause: ' + JSON.stringify(error.message));
653        })
654        this.isJumping = false;
655    }
656
657    // Go to the multi-faceted portrait list page.
658    jumpToGroupDetail(threadId, contactsNum) {
659        let actionData = {
660            uri: 'pages/group_detail/group_detail',
661            params: {
662                threadId: threadId,
663                contactsNum: contactsNum
664            }
665        };
666        this.isJumping = false;
667        router.push(actionData);
668    }
669
670    setSelectLock() {
671        this.isSelectLockMsg = !this.isSelectLockMsg;
672    }
673
674    setSelectLockChange(e) {
675        // Delete the checkbox lockout event.
676        this.isSelectLockMsg = e.checked;
677    }
678
679    // Querying All Lists
680    queryAllMessages() {
681        HiLog.i(TAG, 'queryAllMessages, start');
682        let actionData: LooseObject = {};
683        this.limit = StringUtil.getLimitForSession(this.page);
684        if (this.hasAggregate) {
685            actionData.smsType = common.sms_type.COMMON;
686        }
687        actionData.page = this.page;
688        actionData.limit = this.limit;
689        actionData.orderByTimeDesc = true;
690        ConversationListService.getInstance().querySessionList(actionData, result => {
691            if (result.code == common.int.SUCCESS) {
692                let res = this.buildSessionList(result);
693                this.messageList = this.messageList.concat(res);
694                this.conversationListDataSource.refresh(this.messageList);
695                this.total = result.total;
696                this.hasNoOrdinaryMsg = this.total == 0 ? true : false;
697                this.hasInfoMsg = result.hasInfoMsg;
698                if (this.messageList.length < this.total) {
699                    this.page++;
700                    setTimeout(() => {
701                        this.queryAllMessages();
702                    },this.page == 2 ? 200 : 100);
703                } else {
704                    this.page = 0;
705                    globalThis.needToUpdate = false;
706                }
707            }
708        }, null);
709    }
710
711    buildSessionList(result) {
712        let res = [];
713        result.response.forEach(item => {
714            // Inherit selected items
715            if(this.isMultipleSelectState) {
716                this.messageList.some(oldItem => {
717                    if (item.threadId === oldItem.threadId) {
718                        item.isCbChecked = oldItem.isCbChecked;
719                        return true;
720                    }
721                });
722            }
723            let obj: LooseObject = {};
724            obj = item;
725            obj.isDelShow = false;
726            obj.itemLeft = 0;
727            obj.photoFirstName = common.string.EMPTY_STR;
728            if( obj.name !== common.string.EMPTY_STR && this.reg.test(obj.name.substring(0, 1))) {
729                obj.photoFirstName = obj.name.substring(0, 1).toUpperCase();
730            }
731            obj.portraitColor = AvatarColor.background.Color[Math.abs(parseInt(obj.threadId, 10)) % 6];
732            // Time Conversion
733            DateUtil.convertDateFormatForItem(item, false);
734            // Processes MMS content display.
735            this.dealMmsListContent(item);
736            res.push(obj);
737        });
738        return res;
739    }
740
741    dealMmsListContent(item) {
742        if (item.hasMms && item.hasAttachment) {
743            if (item.content == common.string.EMPTY_STR) {
744                item.content = $r('app.string.attachment_no_subject');
745            } else {
746                item.content = $r('app.string.attachment', item.content);
747            }
748        }
749        if (item.hasMms && !item.hasAttachment && item.content == common.string.EMPTY_STR) {
750            item.content = $r('app.string.no_subject');
751        }
752    }
753
754    // The SM details page is displayed.
755    clickInfoToConversation(index) {
756        if (this.resetTouch()) {
757            return;
758        }
759        // If multiple options are selected, the system responds to CheckBox.
760        if (this.isMultipleSelectState) {
761            if (this.messageList[index] == null || this.messageList[index] == undefined) {
762                return;
763            }
764            this.messageList[index].isCbChecked = !this.messageList[index].isCbChecked;
765            this.setConversationCheckAll(common.int.CHECKBOX_SELECT_UNKNOWN);
766            return;
767        }
768        if (this.isJumping) {
769            return;
770        }
771        this.isJumping = true;
772        // If the contact has unread information, a message needs to be sent to the backend PA to mark all information
773        // of the contact as read.
774        if (this.messageList[index]?.countOfUnread > common.int.MESSAGE_CODE_ZERO) {
775            this.markAllAsReadByIndex(index);
776        }
777        this.jumpToConversationPage(this.messageList[index]);
778    }
779
780    // The session details page is displayed.
781    jumpToConversationPage(item) {
782        router.push({
783            uri: 'pages/conversation/conversation',
784            params: {
785                strContactsNumber: item?.telephone,
786                strContactsNumberFormat: item?.telephoneFormat,
787                strContactsName: item?.name,
788                contactsNum: item?.contactsNum,
789                threadId: item?.threadId,
790                isDraft: item?.isDraft,
791                draftContent: item?.content,
792                searchContent: this.inputValueOfSearch
793            }
794        });
795    }
796
797    markAllAsReadByIndex(index) {
798        let threadId: number = this.messageList[index]?.threadId;
799        let actionData: LooseObject = {};
800        actionData.threadId = threadId;
801        actionData.hasRead = common.is_read.UN_READ;
802        NotificationService.getInstance().cancelMessageNotify(actionData);
803        ConversationListService.getInstance().markAllToRead(actionData);
804        let tempMsgList: Array<LooseObject> = this.messageList;
805        for (let msg of tempMsgList) {
806            if (threadId == msg.threadId) {
807                // Controls the display of unread icons in the list
808                msg.countOfUnread = common.int.MESSAGE_CODE_ZERO;
809            }
810        }
811        this.messageList = tempMsgList;
812        this.conversationListDataSource.refresh(this.messageList);
813        this.setListItemTransX(0);
814        this.statisticalData();
815    }
816
817    deleteAction(idx) {
818        this.delItem = idx;
819        let element = this.messageList[idx];
820        this.strMsgDeleteDialogTip = $r('app.string.msg_delete_dialog_tip1');
821        element.isCbChecked = true;
822        this.hasLockMsg = this.judgehasLockMsg();
823    }
824
825    checkHasCommonMessage() {
826        return this.messageList.length > 0;
827    }
828
829    showMultipleSelectView() {
830        this.resetTouch();
831        if (this.checkHasCommonMessage()) {
832            this.isMultipleSelectState = true;
833            this.setConversationCheckAll(common.int.CHECKBOX_SELECT_UNKNOWN)
834        }
835    }
836}
837