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