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