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 dataShare.createDataShareHelper(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