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