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 : number) {
215        if (this.messageList[index]) {
216            // Check whether the left slide button exists. If yes, the button cannot be clicked.
217            if (this.messageList[index]?.isDelShow != null && this.messageList[index].isDelShow) {
218                return;
219            }
220            // Touch and hold a list to display the selection and deletion functions.
221            HiLog.i(TAG, 'conversationLongPress, index: ' + index);
222            let oldStates = this.messageList[index].isCbChecked;
223            if (this.isMultipleSelectState) {
224                this.messageList[index].isCbChecked = !this.messageList[index].isCbChecked;
225            } else {
226                this.messageList[index].isCbChecked = true;
227                this.isMultipleSelectState = true;
228            }
229            if (this.messageList[index].isCbChecked != oldStates && this.messageList[index].isCbChecked == true) {
230                this.conversationSelectedNumber ++;
231            }
232            this.conversationListDataSource.notifyDataChange(index);
233            this.setConversationCheckAll(common.int.CHECKBOX_SELECT_UNKNOWN);
234        }
235    }
236
237    setConversationCheckAll(selectType) {
238        // Check whether all items are selected.
239        if (!this.isMultipleSelectState) {
240            return;
241        }
242        if (selectType == common.int.CHECKBOX_SELECT_ALL) {
243            this.conversationSelectedNumber = this.messageList.length;
244            this.isConversationCheckAll = true;
245        } else if (selectType == common.int.CHECKBOX_SELECT_NONE) {
246            this.conversationSelectedNumber = common.int.MESSAGE_CODE_ZERO;
247            this.isConversationCheckAll = false;
248        } else {
249            // The default value is CHECKBOX_SELECT_UNKNOWN. Check whether there is any unselected item.
250            this.isConversationCheckAll = true;
251            this.conversationSelectedNumber = 0;
252            this.messageList.forEach((element, index, array) => {
253                if (element.isCbChecked) {
254                    this.conversationSelectedNumber++;
255                } else if (this.isConversationCheckAll) {
256                    this.isConversationCheckAll = false;
257                }
258            })
259            this.conversationListDataSource.refresh(this.messageList);
260        }
261        if (this.isConversationCheckAll) {
262            // Select All Status
263            this.strCheckBoxSelectTip = $r('app.string.msg_deselect_all');
264        } else {
265            // Non-Select All Status
266            this.strCheckBoxSelectTip = $r('app.string.msg_select_all');
267        }
268    }
269
270    backSearch() {
271        this.isShowSearchBack = false;
272        this.isSearchCoverage = false;
273        //  this.$element('searchBox').focus({
274        //    focus: false
275        //  });
276        this.isSearchFocusable = false
277        this.inputValueOfSearch = common.string.EMPTY_STR;
278        this.isSearchStatus = true;
279        this.isNewSms = true;
280        this.searchResultList.sessionList = [];
281        this.searchResultList.contentList = [];
282    }
283
284    // Reset touch event, which is used to reset an item that has been moved by sliding left
285    // when other buttons are pressed.
286    resetTouch() {
287        if (this.itemTouchedIdx !== -1) {
288            let itemTouched = this.messageList[this.itemTouchedIdx];
289            if (itemTouched == undefined) {
290                return false;
291            }
292            if (itemTouched.isDelShow) {
293                itemTouched.isDelShow = false;
294                this.setListItemTransX(0);
295                return true;
296            }
297        } else if (this.showMarkAllAsRead) {
298            this.showMarkAllAsRead = false;
299            this.setInfoItemTransX(0);
300            return true;
301        }
302        return false;
303    }
304
305    // Touch event for information list
306    touchStart(event: GestureEvent, index: number) {
307        if (this.isMultipleSelectState) {
308            return;
309        }
310        if (this.showMarkAllAsRead) {
311            // If the last touch is a notification item, the notification item will be reset.
312                  this.setInfoItemTransX(0);
313                  setTimeout(() => {
314                    this.showMarkAllAsRead = false;
315                  }, 200);
316        } else {
317            // Check whether the current touch item is the same as that of a touch item.
318            // If not, reset the previous touch item.
319            if (this.itemTouchedIdx !== -1 && index !== this.itemTouchedIdx) {
320                let itemTouched = this.messageList[this.itemTouchedIdx];
321                if (itemTouched != undefined && itemTouched != null && itemTouched.isDelShow) {
322                    this.setListItemTransX(0);
323                    itemTouched.isDelShow = false;
324                }
325            }
326        }
327        this.itemTouchedIdx = index;
328        let item = this.messageList[this.itemTouchedIdx];
329        if (item == null || item == undefined) {
330            return;
331        }
332        if (item.countOfUnread > 0) {
333            this.operateBtnW = common.int.OPERATE_UNREAD_WIDTH;
334        } else {
335            this.operateBtnW = common.int.OPERATE_DELETE_WIDTH;
336        }
337    }
338
339    touchMove(event: GestureEvent, index: number) {
340        if (this.isMultipleSelectState) {
341            return;
342        }
343        // offsetX indicates the offset. The value range is [-operateBtnW, 0].
344        let offsetX = event.offsetX;
345        // If the displacement is less than 2, there is no sliding.
346        if (Math.abs(offsetX) <= 2) {
347            return;
348        }
349        let item = this.messageList[this.itemTouchedIdx];
350        let transX = offsetX;
351        if (item && item.isDelShow) {
352            if (event.offsetX - this.operateBtnW <= 0) {
353                transX = event.offsetX - this.operateBtnW
354            } else {
355                // Slide right to close
356                transX = 0
357            }
358        } else {
359            if (event.offsetX + this.operateBtnW >= 0) {
360                transX = event.offsetX
361            } else {
362                // Slide left to maximum width
363                transX = 0 - this.operateBtnW;
364            }
365        }
366        this.setListItemTransX(transX);
367    }
368
369    touchEnd(event: GestureEvent, index: number) {
370        if (this.isMultipleSelectState) {
371            return;
372        }
373        // offsetX indicates the offset. The value range is [-operateBtnW, 0].
374        let offsetX = event.offsetX;
375        let item = this.messageList[this.itemTouchedIdx];
376        if (offsetX + (this.operateBtnW / 2) >= 0) {
377            this.setListItemTransX(0);
378            item.isDelShow = false;
379        } else {
380            this.setListItemTransX(0 - this.operateBtnW);
381            item.isDelShow = true;
382        }
383    }
384
385    setListItemTransX(transX) {
386        let item = this.messageList[this.itemTouchedIdx];
387        if (item) {
388            if (transX <= 0) {
389                item.itemLeft = transX;
390            } else {
391                item.itemLeft = 0;
392            }
393        }
394        // Used to refresh the interface.
395        this.flushTranslate = !this.flushTranslate;
396    }
397
398    setInfoItemTransX(disX) {
399        if (disX >= 0) {
400            this.infoLeft = -disX;
401        } else {
402            this.infoLeft = -this.operateBtnW - disX;
403        }
404    }
405
406    clickConversationCheckAll() {
407        // Select All/Deselect All
408        if (this.isConversationCheckAll) {
409            for (let element of this.messageList) {
410                element.isCbChecked = false;
411            }
412            this.setConversationCheckAll(common.int.CHECKBOX_SELECT_NONE);
413        } else {
414            // Not Select All --> Select All
415            for (let element of this.messageList) {
416                element.isCbChecked = true;
417            }
418            this.setConversationCheckAll(common.int.CHECKBOX_SELECT_ALL);
419        }
420        this.conversationListDataSource.notifyDataReload();
421    }
422
423    clickConversationDelete() {
424        // Button Delete
425        if (this.conversationSelectedNumber == common.int.MESSAGE_CODE_ZERO) {
426            return;
427        }
428        // Delete a record.
429        if (this.conversationSelectedNumber == common.int.MESSAGE_CODE_ONE) {
430            this.strMsgDeleteDialogTip = $r('app.string.msg_delete_dialog_tip1');
431        } else if (this.conversationSelectedNumber == this.messageList.length) {
432            // Delete All
433            this.strMsgDeleteDialogTip = $r('app.string.msg_delete_dialog_tip3');
434        } else {
435            // Delete multiple records.
436            this.strMsgDeleteDialogTip = $r('app.string.msg_delete_dialog_tip2', this.conversationSelectedNumber);
437        }
438        // Locked or not
439        this.hasLockMsg = this.judgehasLockMsg()
440    }
441
442    judgehasLockMsg() {
443        let hasLockMsg = false;
444        for (let element of this.messageList) {
445            if (element.isCbChecked && element.isLock) {
446                hasLockMsg = true;
447                break;
448            }
449        }
450        return hasLockMsg;
451    }
452
453    onBackPress() {
454        HiLog.i(TAG, 'onBackPress');
455        // Key returned by the system. The value true indicates interception.
456        if (this.isMultipleSelectState) {
457            for (let element of this.messageList) {
458                element.isCbChecked = false;
459            }
460            this.isMultipleSelectState = false;
461            return true;
462        }
463        if (!this.isSearchStatus) {
464            this.backSearch();
465            return true;
466        }
467        return false;
468    }
469
470    deleteDialogConfirm() {
471        this.setDelShow();
472        let mmsList: Array<LooseObject> = [];
473        let threadIds: Array<number> = [];
474        for (let element of this.messageList) {
475            if (element.isCbChecked) {
476                threadIds.push(element.threadId);
477            } else {
478                mmsList.push(element);
479            }
480        }
481        this.isMultipleSelectState = false;
482        this.isSelectLockMsg = false;
483        this.messageList = mmsList;
484        this.conversationListDataSource.refresh(this.messageList);
485        this.total = this.messageList.length;
486        this.hasNoOrdinaryMsg = this.total == 0 ? true : false;
487
488        let actionData: LooseObject = {};
489        actionData.threadIds = threadIds;
490        actionData.hasRead = common.is_read.UN_READ;
491        NotificationService.getInstance().cancelMessageNotify(actionData);
492        NotificationService.getInstance().updateBadgeNumber();
493        actionData.hasRead = null;
494        ConversationListService.getInstance().deleteMessageById(actionData, null, null);
495    }
496
497    deleteDialogCancel() {
498        if (!this.isMultipleSelectState) {
499            this.messageList[this.delItem].isCbChecked = false;
500        }
501        // Cancel Ejection
502        if (this.isSelectLockMsg) {
503            this.isSelectLockMsg = false;
504        }
505    }
506
507    setDelShow() {
508        if (this.itemTouchedIdx >= 0) {
509            let item = this.messageList[this.itemTouchedIdx];
510            this.setListItemTransX(0);
511            item.isDelShow = false;
512        }
513    }
514
515    clickToMarkAllAsRead() {
516        let threadIds: Array<number> = [];
517        for (let mms of this.messageList) {
518            if (mms.countOfUnread > common.int.MESSAGE_CODE_ZERO) {
519                threadIds.push(mms.threadId);
520            }
521        }
522        let actionData: LooseObject = {};
523        NotificationService.getInstance().setBadgeNumber(0);
524        actionData.threadIds = threadIds;
525        actionData.hasRead = common.is_read.UN_READ;
526        NotificationService.getInstance().cancelMessageNotify(actionData);
527        ConversationListService.getInstance().markAllToRead(actionData);
528        this.unreadTotalOfInfo = 0;
529        this.unreadTotal = 0;
530        let tempMsgList: Array<LooseObject> = this.messageList;
531        for (let msg of tempMsgList) {
532            if (threadIds.indexOf(msg.threadId) != -1) {
533                msg.countOfUnread = common.int.MESSAGE_CODE_ZERO;
534            }
535        }
536        this.messageList = tempMsgList;
537        this.conversationListDataSource.refresh(this.messageList);
538    }
539
540    jumpToSettingsPage() {
541        router.push({
542            uri: 'pages/settings/settings',
543            params: {
544                pageFlag: 'settingsDetail',
545            }
546        });
547    }
548
549    subscribe() {
550        let events = [common.string.RECEIVE_TRANSMIT_EVENT]
551        let commonEventSubscribeInfo = {
552            events: events
553        };
554        commonEvent.createSubscriber(commonEventSubscribeInfo, this.createSubscriberCallBack.bind(this));
555
556    }
557
558    subscriberCallBack(err, data) {
559        this.page = 0;
560        this.messageList = [];
561        this.requestItem();
562        // Collecting Unread Information
563        this.statisticalData();
564    }
565
566    // Unsubscribe
567    unSubscribe() {
568        HiLog.i(TAG, 'unSubscribe');
569        if (this.commonEventData != null) {
570            commonEvent.unsubscribe(this.commonEventData, () => {
571                HiLog.i(TAG, 'unSubscribe, success');
572            });
573        }
574    }
575
576    createSubscriberCallBack(err, data) {
577        this.commonEventData = data;
578        // Received subscription
579        commonEvent.subscribe(this.commonEventData, this.subscriberCallBack.bind(this));
580    }
581
582    // statistical data
583    statisticalData() {
584        let that = this;
585        ConversationListService.getInstance().statisticalData(result => {
586            if (result.code == common.int.SUCCESS) {
587                // Total number of lists
588                that.unreadTotal = result.response.totalListCount;
589                // Unreading of notification messages
590                that.unreadTotalOfInfo = result.response.unreadTotalOfInfo;
591                NotificationService.getInstance().setBadgeNumber(Number(that.unreadTotal));
592            } else {
593                HiLog.w(TAG, 'statisticalData, failed');
594            }
595        }, null);
596    }
597
598    // Obtains the switch value for integrating notification information and displaying contact avatars.
599    getSettingFlagForConvListPage() {
600        let that = this;
601        let result = SettingService.getSettingFlagForConvListPage();
602        if (result) {
603            that.hasAggregate = result.hasAggregate;
604            that.isShowContactHeadIcon = result.isShowContactHeadIcon;
605        }
606    }
607
608    // Obtaining List Data in Pagination Mode
609    requestItem() {
610        if (this.page === 0) {
611            this.page++;
612            this.queryAllMessages();
613        } else {
614            HiLog.i(TAG, 'isLoading');
615        }
616    }
617
618    // The notification page is displayed.
619    clickToInfoMessages(hasAggregate, hasInfoMsg, isSearchStatus) {
620        if (this.resetTouch()) {
621            return;
622        }
623        if (this.isMultipleSelectState) {
624            return;
625        }
626        router.push({
627            uri: 'pages/infomsg/InfoMsg'
628        })
629    }
630
631    // Tap the avatar to go to the contact details page or recipient list page.
632    clickToGroupDetail(index) {
633        if (this.isJumping) {
634            return;
635        }
636        this.isJumping = true;
637        // Determine whether to redirect to the contact details page or to the list page of multiple recipients.
638        var contactsNum = this.messageList[index]?.contactsNum;
639        var telephone = this.messageList[index]?.telephone;
640        if (contactsNum == common.int.MESSAGE_CODE_ONE) {
641            var actionData = {
642                phoneNumber: telephone,
643                pageFlag: common.contactPage.PAGE_FLAG_CONTACT_DETAILS
644            };
645            this.jumpToContact(actionData);
646        } else {
647            let threadId = this.messageList[index]?.threadId;
648            let contactsNum = this.messageList[index]?.contactsNum;
649            this.jumpToGroupDetail(threadId, contactsNum);
650        }
651    }
652
653    // Switching to the Contacts app
654    jumpToContact(actionData) {
655        let str = commonService.commonContactParam(actionData);
656        globalThis.mmsContext.startAbility(str).then((data) => {
657            HiLog.i(TAG, 'jumpToContact, startAbility success');
658        }).catch((error) => {
659            HiLog.e(TAG, 'jumpToContact, failed Cause: ' + JSON.stringify(error.message));
660        })
661        this.isJumping = false;
662    }
663
664    // Go to the multi-faceted portrait list page.
665    jumpToGroupDetail(threadId, contactsNum) {
666        let actionData = {
667            uri: 'pages/group_detail/group_detail',
668            params: {
669                threadId: threadId,
670                contactsNum: contactsNum
671            }
672        };
673        this.isJumping = false;
674        router.push(actionData);
675    }
676
677    setSelectLock() {
678        this.isSelectLockMsg = !this.isSelectLockMsg;
679    }
680
681    setSelectLockChange(e) {
682        // Delete the checkbox lockout event.
683        this.isSelectLockMsg = e.checked;
684    }
685
686    // Querying All Lists
687    queryAllMessages() {
688        HiLog.i(TAG, 'queryAllMessages, start');
689        let actionData: LooseObject = {};
690        this.limit = StringUtil.getLimitForSession(this.page);
691        if (this.hasAggregate) {
692            actionData.smsType = common.sms_type.COMMON;
693        }
694        actionData.page = this.page;
695        actionData.limit = this.limit;
696        actionData.orderByTimeDesc = true;
697        ConversationListService.getInstance().querySessionList(actionData, result => {
698            if (result.code == common.int.SUCCESS) {
699                let res = this.buildSessionList(result);
700                this.messageList = this.messageList.concat(res);
701                this.conversationListDataSource.refresh(this.messageList);
702                this.total = result.total;
703                this.hasNoOrdinaryMsg = this.total == 0 ? true : false;
704                this.hasInfoMsg = result.hasInfoMsg;
705                if (this.messageList.length < this.total) {
706                    this.page++;
707                    setTimeout(() => {
708                        this.queryAllMessages();
709                    },this.page == 2 ? 200 : 100);
710                } else {
711                    this.page = 0;
712                    globalThis.needToUpdate = false;
713                }
714            }
715        }, null);
716    }
717
718    buildSessionList(result) {
719        let res = [];
720        result.response.forEach(item => {
721            // Inherit selected items
722            if(this.isMultipleSelectState) {
723                this.messageList.some(oldItem => {
724                    if (item.threadId === oldItem.threadId) {
725                        item.isCbChecked = oldItem.isCbChecked;
726                        return true;
727                    }
728                });
729            }
730            let obj: LooseObject = {};
731            obj = item;
732            obj.isDelShow = false;
733            obj.itemLeft = 0;
734            obj.photoFirstName = common.string.EMPTY_STR;
735            if( obj.name !== common.string.EMPTY_STR && this.reg.test(obj.name.substring(0, 1))) {
736                obj.photoFirstName = obj.name.substring(0, 1).toUpperCase();
737            }
738            obj.portraitColor = AvatarColor.background.Color[Math.abs(parseInt(obj.threadId, 10)) % 6];
739            // Time Conversion
740            DateUtil.convertDateFormatForItem(item, false);
741            // Processes MMS content display.
742            this.dealMmsListContent(item);
743            res.push(obj);
744        });
745        return res;
746    }
747
748    dealMmsListContent(item) {
749        if (item.hasMms && item.hasAttachment) {
750            if (item.content == common.string.EMPTY_STR) {
751                item.content = $r('app.string.attachment_no_subject');
752            } else {
753                item.content = $r('app.string.attachment', item.content);
754            }
755        }
756        if (item.hasMms && !item.hasAttachment && item.content == common.string.EMPTY_STR) {
757            item.content = $r('app.string.no_subject');
758        }
759    }
760
761    // The SM details page is displayed.
762    clickInfoToConversation(index) {
763        if (this.resetTouch()) {
764            return;
765        }
766        // If multiple options are selected, the system responds to CheckBox.
767        if (this.isMultipleSelectState) {
768            if (this.messageList[index] == null || this.messageList[index] == undefined) {
769                return;
770            }
771            this.messageList[index].isCbChecked = !this.messageList[index].isCbChecked;
772            this.setConversationCheckAll(common.int.CHECKBOX_SELECT_UNKNOWN);
773            return;
774        }
775        if (this.isJumping) {
776            return;
777        }
778        this.isJumping = true;
779        // If the contact has unread information, a message needs to be sent to the backend PA to mark all information
780        // of the contact as read.
781        if (this.messageList[index]?.countOfUnread > common.int.MESSAGE_CODE_ZERO) {
782            this.markAllAsReadByIndex(index);
783        }
784        this.jumpToConversationPage(this.messageList[index]);
785    }
786
787    // The session details page is displayed.
788    jumpToConversationPage(item) {
789        router.push({
790            uri: 'pages/conversation/conversation',
791            params: {
792                strContactsNumber: item?.telephone,
793                strContactsNumberFormat: item?.telephoneFormat,
794                strContactsName: item?.name,
795                contactsNum: item?.contactsNum,
796                threadId: item?.threadId,
797                isDraft: item?.isDraft,
798                draftContent: item?.content,
799                searchContent: this.inputValueOfSearch
800            }
801        });
802    }
803
804    markAllAsReadByIndex(index) {
805        let threadId: number = this.messageList[index]?.threadId;
806        let actionData: LooseObject = {};
807        actionData.threadId = threadId;
808        actionData.hasRead = common.is_read.UN_READ;
809        NotificationService.getInstance().cancelMessageNotify(actionData);
810        ConversationListService.getInstance().markAllToRead(actionData);
811        let tempMsgList: Array<LooseObject> = this.messageList;
812        for (let msg of tempMsgList) {
813            if (threadId == msg.threadId) {
814                // Controls the display of unread icons in the list
815                msg.countOfUnread = common.int.MESSAGE_CODE_ZERO;
816            }
817        }
818        this.messageList = tempMsgList;
819        this.conversationListDataSource.refresh(this.messageList);
820        this.setListItemTransX(0);
821        this.statisticalData();
822    }
823
824    deleteAction(idx) {
825        this.delItem = idx;
826        let element = this.messageList[idx];
827        this.strMsgDeleteDialogTip = $r('app.string.msg_delete_dialog_tip1');
828        element.isCbChecked = true;
829        this.hasLockMsg = this.judgehasLockMsg();
830    }
831
832    checkHasCommonMessage() {
833        return this.messageList.length > 0;
834    }
835
836    showMultipleSelectView() {
837        this.resetTouch();
838        if (this.checkHasCommonMessage()) {
839            this.isMultipleSelectState = true;
840            this.setConversationCheckAll(common.int.CHECKBOX_SELECT_UNKNOWN)
841        }
842    }
843}
844