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