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 common from "../../data/commonData"; 16import commonEvent from "@ohos.commonEventManager"; 17import commonService from "../../service/CommonService"; 18import dateUtil from "../../utils/DateUtil"; 19import featureAbility from "@ohos.ability.featureAbility"; 20import LooseObject from "../../data/LooseObject" 21// Information List Service 22import messageService from "../../service/ConversationListService"; 23// Log tool class 24import HiLog from "../../utils/HiLog"; 25import MmsPreferences from "../../utils/MmsPreferences"; 26import NotificationService from "../../service/NotificationService"; 27// Notification Information 28import router from "@system.router"; 29// Obtain the setting switch. 30import settingService from "../../service/SettingService"; 31import ConversationListDataSource from "../../model/ConversationListDataSource" 32 33const TAG = "InfoMsgController" 34 35let sInfoMsgCtrl; 36 37export default class InfoMsgController { 38 delDialogShow: boolean = false; 39 commonEventData: any = null; 40 svgDelete: string = "icon/ic_public_delete.svg" 41 total: number = 0; 42 strCheckBoxSelectTip: Resource; 43 strMsgDeleteDialogTip: Resource; 44 // Number of selected sessions 45 conversationSelectedNumber: number = 0; 46 // Indicates whether the multi-select state is selected. 47 isMultipleSelectState: boolean = false; 48 isSearchFocusable: boolean = false; 49 // No The session list is selected. 50 isConversationCheckAll: boolean = false; 51 // Value entered in the search box on the information list page 52 inputValueOfSearch: string = ''; 53 // Indicates whether to lock. The default value is false. No. 54 hasLockMsg: boolean = false; 55 isSelectLockMsg: boolean = false; 56 // List of search results 57 searchResultList: LooseObject = { 58 sessionList: [], 59 contentList: [] 60 }; 61 // Search Results Queue 62 searchResultListQueue: Array<any> = []; 63 // Search Text Queue 64 searchTextQueue: Array<any> = []; 65 // Queue timer start flag bit 66 setTimeOutQueueFlag: boolean = false; 67 // Indicates whether to perform redirection to avoid repeated redirection. 68 isJumping: boolean = false; 69 // Indicates whether to display the search return button. By default, the button is not displayed. 70 isShowSearchBack: boolean = false; 71 // The transparent color of the mask is displayed during search. 72 isSearchCoverage: boolean = false; 73 // Display Query All Information 74 isSearchStatus: boolean = true; 75 // Whether to display session search 76 isSearchConversation: boolean = false; 77 // Show Spacer Lines 78 isSearchInterval: boolean = false; 79 // Display Single Information Search 80 isSearchSms: boolean = false; 81 // Display SMS messages when the search result is empty. 82 isSearchNull: boolean = false; 83 // Queue start flag bit 84 queueFlag: boolean = false; 85 // Show Search Status 86 showSearchStatus: string = ''; 87 conversationName: string = ''; 88 // Number of unread notifications. 89 unreadTotalOfInfo: number = 0; 90 messageList: Array<any> = []; 91 numberType: number = 1; 92 // Indicates whether to display the contact profile picture. 93 isShowContactHeadIcon: boolean = true; 94 // Number of search results 95 countOfSearchResult: number = 0; 96 // Display Navigation Bar 97 isNavigationBar: boolean = false; 98 // Search status. Click the search box to enter the search status. 99 searchStatus: boolean = false; 100 // Indicates whether to display the toolbar. The toolbar is not displayed in the search state. 101 showToolBar: boolean = true; 102 // Update the UI. 103 flushTranslate: boolean = true; 104 // Length of the operation button 105 operateBtnW: number = 145; 106 // Data index of the current touch 107 itemTouchedIdx: number = -1; 108 // List pagination, quantity 109 limit: number = 1000; 110 // List pagination, number of pages 111 page: number = 0; 112 // Total number of messages 113 totalMessage: number = 0; 114 // notification conversation list adapters 115 conversationListDataSource: ConversationListDataSource = new ConversationListDataSource(); 116 117 static getInstance() { 118 if (sInfoMsgCtrl == null) { 119 sInfoMsgCtrl = new InfoMsgController(); 120 AppStorage.SetAndLink("InfoMsgController", sInfoMsgCtrl); 121 } 122 return sInfoMsgCtrl; 123 } 124 125 onInit() { 126 HiLog.i(TAG, "onInit"); 127 this.strCheckBoxSelectTip = $r("app.string.msg_select_all"); 128 this.strMsgDeleteDialogTip = $r("app.string.msg_delete_dialog_tip2", this.conversationSelectedNumber); 129 } 130 131 onShow() { 132 HiLog.i(TAG, "onShow"); 133 this.isJumping = false; 134 this.getSettingFlagForConvListPage(); 135 this.page = 0; 136 this.requestItem(); 137 this.subscribeInfo(); 138 let actionData = {}; 139 NotificationService.getInstance().cancelMessageNotify(actionData, res => { 140 }); 141 } 142 143 onHide() { 144 HiLog.i(TAG, "onHide"); 145 this.unsubscribeInfo(); 146 } 147 // Querying List Data 148 queryAllMessages() { 149 let actionData: LooseObject = { 150 page: this.page, 151 limit: this.limit, 152 } 153 actionData.numberType = this.numberType; 154 messageService.querySessionList(actionData, result => { 155 if (result.code == common.int.SUCCESS) { 156 HiLog.i(TAG, "queryAllMessages, Success"); 157 let res = this.buildSessionList(result); 158 this.messageList = res; 159 this.conversationListDataSource.refresh(this.messageList); 160 this.totalMessage = result.total; 161 this.total = this.messageList.length; 162 if (this.totalMessage === this.total) { 163 this.countUnread(); 164 } 165 } else { 166 HiLog.w(TAG, "queryAllMessages, failed"); 167 } 168 }); 169 } 170 171 dealMmsListContent(element) { 172 if (element.hasMms && element.hasAttachment) { 173 if (element.content == common.string.EMPTY_STR) { 174 element.content = $r("app.string.attachment_no_subject"); 175 } else { 176 element.content = $r("app.string.attachment", element.content); 177 } 178 } 179 if (element.hasMms && !element.hasAttachment && element.content == common.string.EMPTY_STR) { 180 element.content = $r("app.string.no_subject"); 181 } 182 } 183 184 buildSessionList(result) { 185 let res = []; 186 result.response.forEach(item => { 187 // Inherit selected items 188 this.messageList.some(oldItem => { 189 if (item.threadId === oldItem.threadId) { 190 item.isCbChecked = oldItem.isCbChecked; 191 return true; 192 } 193 }); 194 let obj: LooseObject = {}; 195 obj = item; 196 obj.itemLeft = 0; 197 obj.isDelShow = false; 198 dateUtil.convertDateFormatForItem(item, false); 199 this.dealMmsListContent(obj); 200 res.push(obj); 201 }); 202 return res; 203 } 204 205 requestItem() { 206 let count = this.page * this.limit; 207 if (this.page === 0) { 208 this.page++; 209 this.queryAllMessages(); 210 } else if (count < this.totalMessage && this.messageList.length > (this.page - 1) * this.limit) { 211 // The restriction on messageList is to prevent multiple requests from being refreshed during initialization 212 this.page++; 213 this.queryAllMessages(); 214 } 215 } 216 // Return to the information list page. 217 back() { 218 router.back(); 219 } 220 // Tap More at the bottom of the screen 221 clickMore() { 222 // this.$element("moreDialog").show(); 223 } 224 // Delete a single piece of information from a notification. 225 clickToDelete() { 226 227 } 228 229 clickSearchBack() { 230 // Click the search return button. 231 this.backSearch(); 232 } 233 234 backSearch() { 235 this.isShowSearchBack = false; 236 this.isSearchCoverage = false; 237 this.isSearchFocusable = false; 238 this.inputValueOfSearch = common.string.EMPTY_STR; 239 this.isSearchStatus = true; 240 this.isSearchNull = false; 241 this.searchStatus = false; 242 this.showToolBar = true; 243 } 244 // Search 245 clickToSearch(text) { 246 this.inputValueOfSearch = text; 247 this.search(text); 248 } 249 // Search on the notification information page. 250 search(text) { 251 let actionData: LooseObject = {}; 252 actionData.inputValue = text 253 this.searchTextAsync(actionData) 254 } 255 256 searchTextAsync(actionData) { 257 actionData.numberType = this.numberType; 258 messageService.searchMessageWithLike(actionData, result => { 259 if (result.code == common.int.SUCCESS) { 260 // Check whether the search result is empty before obtaining the search result. 261 if (this.inputValueOfSearch !== common.string.EMPTY_STR) { 262 this.dealSearchResult(result); 263 } 264 } else { 265 this.searchResultListEmpty(); 266 } 267 }); 268 } 269 270 dealSearchResult(result) { 271 this.searchResultList = { 272 contentList: [], 273 sessionList: [] 274 } 275 this.isSearchStatus = false; 276 this.isSearchCoverage = false; 277 this.dealSearchResultTimeAndName(result); 278 if (this.inputValueOfSearch === result.search) { 279 this.searchResultList = result.resultMap; 280 } 281 } 282 283 dealSearchResultTimeAndName(result) { 284 if (result.resultMap.sessionList) { 285 result.resultMap.sessionList.forEach(session => { 286 session.timeMillisecond = parseInt(session.timeMillisecond); 287 dateUtil.convertDateFormatForItem(session, true); 288 }); 289 } 290 if (result.resultMap.contentList) { 291 result.resultMap.contentList.forEach(content => { 292 content.timeMillisecond = parseInt(content.timeMillisecond); 293 dateUtil.convertDateFormatForItem(content, true); 294 if (content.isFavorite) { 295 content.name = $r("app.string.message_in_favorites"); 296 } 297 }); 298 } 299 } 300 301 searchResultListEmpty() { 302 this.searchResultList = { 303 contentList: [], 304 sessionList: [] 305 } 306 // Display Information List 307 this.isSearchStatus = true; 308 if (this.isShowSearchBack) { 309 this.isSearchCoverage = true; 310 } else { 311 this.isSearchCoverage = false; 312 } 313 } 314 // Check whether the multi-choice status is selected. 315 searchTouchStart() { 316 if (this.isMultipleSelectState) { 317 return false; 318 } 319 this.searchStatus = true; 320 this.showToolBar = false; 321 // Search area touchStart monitoring 322 // x > 125 && x < 600) && (y < 70 && y > 20 323 // var x = event.touches[0].x; 324 // if (isSearchType && x > 80 && x < 560) { 325 // Show New Button 326 this.isShowSearchBack = true; 327 // Mask Display 328 this.isSearchCoverage = true; 329 // Start the input method. 330 setTimeout(() => { 331 this.isSearchFocusable = true; 332 }, common.int.MESSAGE_CODE_THREE_ZERO_ZERO); 333 // } 334 this.resetTouch(); 335 return false; 336 } 337 // Touch and hold a list to display the selection and deletion functions. 338 conversationLongPress(index) { 339 // Check whether the left slide button exists. If yes, the button cannot be clicked. 340 if (this.itemTouchedIdx >= 0 && this.messageList[this.itemTouchedIdx].isDelShow) { 341 return; 342 } 343 // Touch and hold a list to display the selection and deletion functions. 344 this.showToolBar = false; 345 HiLog.i(TAG, "conversationLongPress, index: " + index); 346 if (this.isMultipleSelectState) { 347 this.messageList[index].isCbChecked = !this.messageList[index].isCbChecked; 348 } else { 349 this.messageList[index].isCbChecked = true; 350 this.isMultipleSelectState = true; 351 } 352 this.setConversationCheckAll(common.int.CHECKBOX_SELECT_UNKNOWN); 353 } 354 // Check whether all items are selected. 355 setConversationCheckAll(type) { 356 if (!this.isMultipleSelectState) { 357 return; 358 } 359 if (type == common.int.CHECKBOX_SELECT_NONE) { 360 this.conversationSelectedNumber = common.int.MESSAGE_CODE_ZERO; 361 this.isConversationCheckAll = false; 362 } else if (type == common.int.CHECKBOX_SELECT_ALL) { 363 this.conversationSelectedNumber = this.messageList.length; 364 this.isConversationCheckAll = true; 365 } else { 366 // The default value is CHECKBOX_SELECT_UNKNOWN. Check whether there is any unselected item. 367 this.isConversationCheckAll = true; 368 this.conversationSelectedNumber = common.int.MESSAGE_CODE_ZERO; 369 this.messageList.forEach((item, index, array) => { 370 if (item.isCbChecked) { 371 this.conversationSelectedNumber++; 372 } else if (this.isConversationCheckAll) { 373 this.isConversationCheckAll = false; 374 } 375 }); 376 } 377 if (!this.isConversationCheckAll) { 378 // Non-Select All Status 379 this.strCheckBoxSelectTip = $r("app.string.msg_select_all"); 380 } else { 381 // Select All Status 382 this.strCheckBoxSelectTip = $r("app.string.msg_deselect_all"); 383 } 384 } 385 // The SM details page is displayed. 386 clickInfoToConversation(index) { 387 if (this.resetTouch()) { 388 return; 389 } 390 // If multiple options are selected, the system responds to CheckBox. 391 if (this.isMultipleSelectState) { 392 this.messageList[index].isCbChecked = !this.messageList[index].isCbChecked; 393 this.setConversationCheckAll(common.int.CHECKBOX_SELECT_UNKNOWN); 394 return; 395 } 396 if (this.isJumping) { 397 return; 398 } 399 this.isJumping = true; 400 // If the contact has unread information, a message needs to be sent to the backend PA to mark all information 401 // of the contact as read. 402 if (this.messageList[index]?.countOfUnread > common.int.MESSAGE_CODE_ZERO) { 403 this.markAllAsReadByIndex(index); 404 } 405 this.jumpToConversationPage(this.messageList[index]); 406 } 407 // The session details page is displayed. 408 jumpToConversationPage(item) { 409 router.push({ 410 uri: "pages/conversation/conversation", 411 params: { 412 strContactsNumber: item.telephone, 413 strContactsNumberFormat: item.telephoneFormat, 414 strContactsName: item.name, 415 contactsNum: item.contactsNum, 416 threadId: item.threadId, 417 isDraft: item.isDraft, 418 draftContent: item.content, 419 searchContent: this.inputValueOfSearch 420 } 421 }); 422 } 423 // Searching for a session avatar 424 searchConversationHeadClick(index) { 425 this.headClickedListener(this.searchResultList.sessionList[index]); 426 } 427 428 headClickedListener(item) { 429 // Tap the avatar to go to the contact details page or recipient list page. 430 if (this.isJumping) { 431 return; 432 } 433 if (item.isFavorite != null && item.isFavorite) { 434 return; 435 } 436 var telephone = item.telephone; 437 var contactsNum = item.contactsNum; 438 this.isJumping = true; 439 if (contactsNum == common.int.MESSAGE_CODE_ONE) { 440 var actionData: LooseObject = {}; 441 actionData.phoneNumber = telephone; 442 actionData.pageFlag = common.contractPage.PAGE_FLAG_CONTACT_DETAILS; 443 this.jumpToContract(actionData); 444 } else { 445 let threadId = item.threadId; 446 let contactsNum = item.contactsNum; 447 this.jumpToGroupDetail(threadId, contactsNum); 448 } 449 } 450 // Go to the multi-faceted portrait list page. 451 jumpToGroupDetail(threadId, contactsNum) { 452 let actionData = { 453 uri: "pages/group_detail/group_detail", 454 params: { 455 threadId: threadId, 456 contactsNum: contactsNum 457 } 458 }; 459 this.isJumping = false; 460 router.push(actionData); 461 } 462 // Go to session details. 463 searchConversationClick(index) { 464 this.searchMmsClicked(this.searchResultList.sessionList[index]); 465 } 466 // Go to SMS details. 467 searchMmsClicked(item) { 468 if (item.isFavorite) { 469 router.push({ 470 uri: "pages/my_star/my_star", 471 params: { 472 searchContent: this.inputValueOfSearch 473 } 474 }); 475 } else { 476 this.jumpToConversationPage(item); 477 } 478 } 479 // Clicking a profile picture to jump to the contact details page or the list page of multiple recipients 480 searchSmsHeadClick(index) { 481 this.headClickedListener(this.searchResultList.contentList[index]); 482 } 483 // The session details page is displayed. 484 searchSmsClick(index) { 485 this.searchMmsClicked(this.searchResultList.contentList[index]); 486 } 487 // Slide your finger to exit the search mode. 488 searchCoverageClick() { 489 this.backSearch(); 490 } 491 // Counting the number of unread messages 492 countUnread() { 493 let actionData: LooseObject = {}; 494 let that = this; 495 messageService.statisticalData(actionData, function (result) { 496 if (result.code == common.int.SUCCESS) { 497 // Unreading of notification messages 498 that.unreadTotalOfInfo = result.response.unreadTotalOfInfo; 499 HiLog.i(TAG, "countUnread = " + that.unreadTotalOfInfo); 500 } else { 501 HiLog.w(TAG, "countUnread, statisticalData failed"); 502 } 503 }); 504 } 505 // Mark all unread notifications as read. 506 clickToMarkAllAsReadForInfo() { 507 let actionData = { 508 hasRead: 1, 509 smsType: 1 510 } 511 let threadIds = []; 512 for (let msg of this.messageList) { 513 msg.countOfUnread = common.int.MESSAGE_CODE_ZERO; 514 threadIds.push(msg.threadId); 515 } 516 this.cancelMessageInfoNotify(threadIds, () => { 517 messageService.markAllToRead(actionData); 518 this.unreadTotalOfInfo = 0; 519 }); 520 } 521 522 markAllAsReadByIndex(index) { 523 let item = this.messageList[index]; 524 let threadId = item.threadId; 525 let threadIds = [threadId]; 526 this.cancelMessageInfoNotify(threadIds, () => { 527 // Marks all information about a contact (argument type: array) as read. 528 this.markAllAsRead(threadIds); 529 this.setListItemTransX(0); 530 item.isDelShow = false; 531 }); 532 } 533 534 cancelMessageInfoNotify(threadIds, callback) { 535 let actionData = { 536 threadIds: threadIds, 537 hasRead: 0 538 }; 539 NotificationService.getInstance().cancelMessageNotify(actionData, res => { 540 callback(); 541 }); 542 } 543 544 markAllAsRead(threadIds) { 545 let tempMsgList = this.messageList; 546 // Marks all information about a contact (argument type: array) as read. 547 let valueBucket = { 548 "unread_count": 0, 549 }; 550 let actionData: LooseObject = {}; 551 actionData.threadIds = threadIds; 552 actionData.valueBucket = valueBucket; 553 actionData.hasRead = 1; 554 // Update data marked read to 0 555 messageService.markAllAsRead(actionData); 556 for (let msg of tempMsgList) { 557 if (threadIds.indexOf(msg.threadId) > common.int.FAILURE) { 558 // Controls the display of unread icons in the list 559 msg.countOfUnread = common.int.MESSAGE_CODE_ZERO; 560 } 561 } 562 this.messageList = tempMsgList; 563 this.conversationListDataSource.refresh(this.messageList); 564 this.unreadTotalOfInfo = this.unreadTotalOfInfo - threadIds.length; 565 } 566 567 selectInMoreMenu(menuId: number) { 568 if (menuId == 1) { 569 // Delete 570 this.isMultipleSelectState = true; 571 this.showToolBar = false; 572 this.setConversationCheckAll(common.int.CHECKBOX_SELECT_UNKNOWN); 573 } else { 574 // The harassment blocking page is displayed, which is in the Phone Manager app. 575 } 576 } 577 // Button Delete 578 clickConversationDelete() { 579 if (this.conversationSelectedNumber == common.int.MESSAGE_CODE_ZERO) { 580 return; 581 } 582 if (this.conversationSelectedNumber == common.int.MESSAGE_CODE_ONE) { 583 this.strMsgDeleteDialogTip = $r("app.string.msg_delete_dialog_tip1"); 584 } else if (this.conversationSelectedNumber == this.messageList.length) { 585 this.strMsgDeleteDialogTip = $r("app.string.msg_delete_dialog_tip3"); 586 } else { 587 this.strMsgDeleteDialogTip = $r("app.string.msg_delete_dialog_tip2", this.conversationSelectedNumber); 588 } 589 this.hasLockMsg = (this.messageList.some((element, index) => element.isCbChecked && element.isLock)); 590 } 591 592 checkSelectedNumberIsEmpty() { 593 return this.conversationSelectedNumber == common.int.MESSAGE_CODE_ZERO 594 } 595 // Cancel Ejection 596 deleteDialogCancel() { 597 if (this.isSelectLockMsg) { 598 this.isSelectLockMsg = false; 599 } 600 } 601 602 setSelectLock() { 603 this.isSelectLockMsg = !this.isSelectLockMsg; 604 } 605 // Delete the checkbox lockout event. 606 setSelectLockChange(event) { 607 this.isSelectLockMsg = event.checked; 608 } 609 610 deleteDialogConfirm() { 611 this.setDelShow(); 612 let mmsList = []; 613 let threadIds = []; 614 let lockSessionIds = []; 615 for (let item of this.messageList) { 616 if (item.isCbChecked) { 617 if (item.isLock && !this.isSelectLockMsg) { 618 lockSessionIds.push(item.threadId); 619 mmsList.push(item); 620 } else { 621 threadIds.push(item.threadId); 622 } 623 } else { 624 mmsList.push(item); 625 } 626 } 627 this.isMultipleSelectState = false; 628 this.showToolBar = true; 629 this.isSelectLockMsg = false; 630 this.messageList = mmsList; 631 this.conversationListDataSource.refresh(this.messageList); 632 this.total = mmsList.length; 633 if (this.total == 0) { 634 router.back(); 635 } 636 this.deleteNotifyMessageInfo(threadIds, lockSessionIds, () => { 637 this.deleteMessageInfoByThreadIds(threadIds, lockSessionIds); 638 }); 639 } 640 641 setDelShow() { 642 if (this.itemTouchedIdx >= 0) { 643 let item = this.messageList[this.itemTouchedIdx]; 644 this.setListItemTransX(0); 645 item.isDelShow = false; 646 } 647 }; 648 649 deleteNotifyMessageInfo(threadIds, lockSessionIds, callback) { 650 let sessionIds = []; 651 if (lockSessionIds.length > 0) { 652 sessionIds.push(lockSessionIds); 653 } 654 if (threadIds.length > 0) { 655 sessionIds.push(threadIds); 656 } 657 this.cancelMessageInfoNotify(sessionIds, callback); 658 } 659 660 deleteMessageInfoByThreadIds(threadIds, lockSessionIds) { 661 let actionData: LooseObject = {}; 662 if (threadIds.length > 0) { 663 actionData.threadIds = threadIds; 664 messageService.deleteMessageById(actionData); 665 } 666 if (lockSessionIds.length > 0) { 667 actionData.threadIds = lockSessionIds; 668 messageService.dealMessageLockContent(actionData, res => { 669 actionData.hasLock = 0; 670 messageService.deleteMessageBySessionIdsAndLock(actionData); 671 }); 672 } 673 } 674 // Select All/Deselect All 675 clickConversationCheckAll() { 676 if (this.isConversationCheckAll) { 677 // Select All --> Deselect All 678 for (let item of this.messageList) { 679 item.isCbChecked = false; 680 } 681 this.setConversationCheckAll(common.int.CHECKBOX_SELECT_NONE); 682 } else { 683 // Not Select All --> Select All 684 for (let item of this.messageList) { 685 item.isCbChecked = true; 686 } 687 this.setConversationCheckAll(common.int.CHECKBOX_SELECT_ALL); 688 } 689 } 690 691 onBackPress() { 692 // Key returned by the system. The value true indicates interception. 693 if (this.isMultipleSelectState) { 694 for (let element of this.messageList) { 695 element.isCbChecked = false; 696 } 697 this.isMultipleSelectState = false; 698 this.showToolBar = true; 699 return true; 700 } 701 return false; 702 } 703 // Tap the avatar to go to the contact details page or recipient list page. 704 clickToGroupDetail(index) { 705 if (this.isJumping) { 706 return; 707 } 708 this.isJumping = true; 709 // Determine whether to redirect to the contact details page or to the list page of multiple recipients. 710 var contactsNum = this.messageList[index]?.contactsNum; 711 var telephone = this.messageList[index]?.telephone; 712 if (contactsNum == common.int.MESSAGE_CODE_ONE) { 713 var actionData = { 714 phoneNumber: telephone, 715 pageFlag: common.contractPage.PAGE_FLAG_CONTACT_DETAILS 716 }; 717 this.jumpToContract(actionData); 718 } else { 719 let threadId = this.messageList[index]?.threadId; 720 let contactsNum = this.messageList[index]?.contactsNum; 721 this.jumpToGroupDetail(threadId, contactsNum); 722 } 723 } 724 725 exitConversationSelect() { 726 this.onBackPress(); 727 } 728 729 touchStart(event: GestureEvent, index: number) { 730 if (this.isMultipleSelectState) { 731 return; 732 } 733 // Check whether the current touch item is the same as that of a touch item. 734 // If not, reset the previous touch item. 735 if (this.itemTouchedIdx !== -1 && index !== this.itemTouchedIdx) { 736 let itemTouched = this.messageList[this.itemTouchedIdx]; 737 if (itemTouched != undefined && itemTouched != null && itemTouched.isDelShow) { 738 this.setListItemTransX(0); 739 itemTouched.isDelShow = false; 740 } 741 } 742 this.itemTouchedIdx = index; 743 let item = this.messageList[this.itemTouchedIdx]; 744 if (item.countOfUnread > 0) { 745 this.operateBtnW = common.int.OPERATE_UNREAD_WIDTH; 746 } else { 747 this.operateBtnW = common.int.OPERATE_DELETE_WIDTH; 748 } 749 } 750 751 resetTouch() { 752 if (this.itemTouchedIdx !== -1) { 753 let item = this.messageList[this.itemTouchedIdx]; 754 if (item == undefined) { 755 return false; 756 } 757 if (item.isDelShow) { 758 item.isDelShow = false; 759 this.setListItemTransX(0); 760 return true; 761 } 762 } 763 return false; 764 } 765 766 touchMove(event: GestureEvent, index: number) { 767 if (this.isMultipleSelectState) { 768 return; 769 } 770 // offsetX indicates the offset. The value range is [-operateBtnW, 0]. 771 let offsetX = event.offsetX; 772 // If the displacement is less than 2, there is no sliding. 773 if (Math.abs(offsetX) <= 2) { 774 return; 775 } 776 let item = this.messageList[this.itemTouchedIdx]; 777 let transX = offsetX; 778 if (item.isDelShow) { 779 if (event.offsetX - this.operateBtnW <= 0) { 780 transX = event.offsetX - this.operateBtnW 781 } else { 782 // Slide right to close 783 transX = 0 784 } 785 } else { 786 if (event.offsetX + this.operateBtnW >= 0) { 787 transX = event.offsetX 788 } else { 789 // Slide left to maximum width 790 transX = 0 - this.operateBtnW; 791 } 792 } 793 this.setListItemTransX(transX); 794 } 795 796 deleteAction(idx) { 797 let element = this.messageList[idx]; 798 this.strMsgDeleteDialogTip = $r("app.string.msg_delete_dialog_tip1"); 799 element.isCbChecked = true; 800 this.hasLockMsg = (this.messageList.some((element, index) => element.isCbChecked && element.isLock)); 801 } 802 803 touchEnd(event: GestureEvent, index: number) { 804 if (this.isMultipleSelectState) { 805 return; 806 } 807 // offsetX indicates the offset. The value range is [-operateBtnW, 0]. 808 let offsetX = event.offsetX; 809 let item = this.messageList[this.itemTouchedIdx]; 810 if (offsetX + (this.operateBtnW / 2) >= 0) { 811 this.setListItemTransX(0); 812 item.isDelShow = false; 813 } else { 814 this.setListItemTransX(0 - this.operateBtnW); 815 item.isDelShow = true; 816 } 817 } 818 // Subscribe to New Messages Received 819 subscribeInfo() { 820 HiLog.i(TAG, "subscribeInfo, start"); 821 let events = [common.string.RECEIVE_TRANSMIT_EVENT] 822 let commonEventSubscribeInfo = { 823 events: events 824 }; 825 commonEvent.createSubscriber(commonEventSubscribeInfo, this.createSubscriberCallBack.bind(this)); 826 } 827 828 setListItemTransX(transX) { 829 let item = this.messageList[this.itemTouchedIdx]; 830 if (item) { 831 if (transX <= 0) { 832 item.itemLeft = transX; 833 } else { 834 item.itemLeft = 0; 835 } 836 } 837 // Used to refresh the interface. 838 this.flushTranslate = !this.flushTranslate; 839 } 840 841 createSubscriberCallBack(err, data) { 842 this.commonEventData = data; 843 // Received subscription 844 commonEvent.subscribe(this.commonEventData, this.subscriberCallBack.bind(this)); 845 } 846 847 subscriberCallBack(err, data) { 848 this.page = 1; 849 this.queryAllMessages(); 850 } 851 // Unsubscribe 852 unsubscribeInfo() { 853 if (this.commonEventData != null) { 854 commonEvent.unsubscribe(this.commonEventData, () => { 855 HiLog.i(TAG, "unsubscribeInfo, success"); 856 }); 857 } 858 } 859 // Switching to the Contacts app 860 jumpToContract(actionData) { 861 var str = commonService.commonContractParam(actionData); 862 globalThis.mmsContext.startAbility(str).then((data) => { 863 }).catch((error) => { 864 HiLog.e(TAG, "jumpToContract, failed: " + JSON.stringify(error.message)); 865 }) 866 this.isJumping = false; 867 } 868 // Obtains the switch value for integrating notification information and displaying contact avatars. 869 getSettingFlagForConvListPage() { 870 let result = settingService.getSettingFlagForConvListPage(); 871 if (result) { 872 this.isShowContactHeadIcon = result.isShowContactHeadIcon; 873 } 874 } 875} 876