1/* 2 * Copyright (c) 2021-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 */ 15 16import { backBar } from "../common/components/backBar"; 17import { alphabetIndexerComponent } from "../common/components/alphabeticalIndex"; 18import { textInput } from "../common/components/search"; 19import router from '@ohos.router'; 20import bundle from "@ohos.bundle"; 21import abilityAccessCtrl from '@ohos.abilityAccessCtrl'; 22import audio from '@ohos.multimedia.audio' 23import camera from '@ohos.multimedia.camera' 24import { groups, userGrantPermissions, permissionGroupPermissions, globalGroup } from "../common/model/permissionGroup"; 25import { permissionGroups, permissionGroupIds, showSubpermissionsGrop } from "../common/model/permissionGroup"; 26import { makePy } from "../common/utils/utils"; 27import Constants from '../common/utils/constant'; 28 29var TAG = 'PermissionManager_MainAbility:' 30 31@Extend(Image) function customizeImage(width: number, height: number) { 32 .objectFit(ImageFit.Contain) 33 .width(width) 34 .height(height) 35}; 36 37interface applicationPermissions { 38 'bundleName': string, 39 'api': number, 40 'iconId': string, 41 'permissions': string[], 42 'labelId': string, 43 'tokenId': number, 44 'groupId': number[] 45}; 46 47interface permissionApplications { 48 'permission': string, 49 'groupName': string, 50 'bundleNames': string[], 51 'icon': string 52}; 53 54interface groupPermission { 55 'group': string, 56 'permissions': string[], 57 'groupName': string, 58 'icon': string, 59 'isShow':boolean 60}; 61 62let textInput_placeholder: any = '' 63const FUZZY_LOCATION_PERMISSION = 'ohos.permission.APPROXIMATELY_LOCATION' 64const PRECISE_LOCATION_PERMISSION = 'ohos.permission.LOCATION' 65 66@Entry 67@Component 68struct authorityManagementPage { 69 @Builder ListItemLayout(item, end) { 70 ListItem() { 71 Row() { 72 Column() { 73 Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) { 74 Row() { 75 Image(item.icon) 76 .customizeImage(Constants.MANAGEMENT_IMAGE_WIDTH, Constants.MANAGEMENT_IMAGE_HEIGHT) 77 .margin({ right: Constants.MANAGEMENT_IMAGE_MARGIN_RIGHT }) 78 Text(item.groupName) 79 .fontSize(Constants.TEXT_MIDDLE_FONT_SIZE) 80 .fontWeight(FontWeight.Medium) 81 .fontColor($r('app.color.label_color')) 82 .flexGrow(Constants.FLEX_GROW) 83 Image($r('app.media.ic_public_arrow_right')) 84 .customizeImage(Constants.IMAGE_WIDTH, Constants.IMAGE_HEIGHT) 85 } 86 .width(Constants.FULL_WIDTH) 87 .height(Constants.MANAGEMENT_ROW_HEIGHT) 88 } 89 if (!end) { 90 Row() { 91 Flex() { 92 Column().width(Constants.MANAGEMENT_TEXT_DECORATION_MARGIN_LEFT) 93 Column() 94 .backgroundColor($r('app.color.text_decoration_color')) 95 .height(Constants.TEXT_DECORATION_HEIGHT) 96 .flexGrow(Constants.FLEX_GROW) 97 } 98 } 99 } 100 }.onClick(() => { 101 if (item.group === 'OTHER' || showSubpermissionsGrop.indexOf(item.group) !== -1) { 102 router.pushUrl({ 103 url: 'pages/authority-secondary', 104 params: { routerData: this.allPermissionApplications, backTitle: item.groupName, group: item.group } 105 }) 106 } else { 107 var dataList = this.allPermissionApplications.filter((ele) => { 108 return ele.groupName === item.group 109 }) 110 111 globalThis.currentPermissionGroup = item.group 112 if(globalGroup.indexOf(item.group) == -1) { 113 router.pushUrl({ 114 url: 'pages/authority-tertiary-groups', 115 params: { routerData: dataList, backTitle: item.groupName } 116 }) 117 }else { 118 if(item.group == 'MICROPHONE') { 119 var audioManager = audio.getAudioManager(); 120 audioManager.isMicrophoneMute().then(value => { 121 router.pushUrl({ 122 url: 'pages/authority-tertiary-groups', 123 params: { routerData: dataList, backTitle: item.groupName, globalIsOn: !value } 124 }) 125 }) 126 }else { 127 let cameraManager = camera.getCameraManager(globalThis.context); 128 let mute = cameraManager.isCameraMuted() 129 router.pushUrl({ 130 url: 'pages/authority-tertiary-groups', 131 params: { routerData: dataList, backTitle: item.groupName, globalIsOn: !mute } 132 }) 133 } 134 } 135 } 136 }) 137 } 138 }.padding({ left: Constants.DEFAULT_PADDING_START, right: Constants.DEFAULT_PADDING_END }) 139 } 140 141 @State allPermissionApplications: permissionApplications [] = [] // All app permissions 142 @State allGroupPermission: groupPermission[] = [] // All group permissions 143 @State currentIndex: number = 0 144 @State @Watch("getLabelAndIcon") ready: boolean = false 145 @Builder TabBuilder(index: number) { 146 Flex({ alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { 147 Text(index ? $r('app.string.application') : $r('app.string.authority')) 148 .fontColor(this.currentIndex == index ? $r('app.color.button_color') : $r('app.color.label_color')) 149 .fontWeight(this.currentIndex == index ? FontWeight.Bold : FontWeight.Regular) 150 .lineHeight(Constants.TEXT_LINE_HEIGHT) 151 if(this.currentIndex == index) { 152 Row().width(Constants.FULL_WIDTH).height(Constants.TAB_DECORATION_HEIGHT) 153 .backgroundColor($r('app.color.button_color')) 154 .position({ y: Constants.TAB_DECORATION_POSITION_Y }) 155 } 156 }.height(Constants.TAB_HEIGHT) 157 } 158 159 /** 160 * Convert the permission array into key, value key-value objects for easy sorting 161 * @param {Array} order User rights 162 * @return {Object} return the processed object 163 */ 164 orderDict(order) { 165 let result = {}; 166 for (let i = 0; i < order.length; i++) { 167 let key = order[i]; 168 result[key] = i; 169 } 170 return result; 171 } 172 173 /** 174 * Compare and sort the permission array according to the permission key value 175 * @param {String} prop Sort by permission 176 * @param {Object} orderSort objects to be sorted 177 * @return {Array} Returns a sorted array of permissions 178 */ 179 compare(prop, orderSort) { 180 return function(a, b) { 181 let aSortValue = orderSort[a[prop]]; 182 let bSortValue = orderSort[b[prop]]; 183 if (aSortValue == undefined) { 184 throw new Error('当前的字段不在排序列表里:' + a[prop]); 185 } 186 if (bSortValue == undefined) { 187 throw new Error('当前的字段不在排序列表里:' + b[prop]); 188 } 189 return aSortValue - bSortValue; 190 } 191 } 192 193 /** 194 * Get all app permission information 195 */ 196 async getAllBundlePermissions() { 197 for (let i = 0; i < globalThis.initialGroups.length; i++) { 198 await this.deduplicationPermissions(globalThis.initialGroups[i]); 199 } 200 this.getAllGroupPermission(); 201 this.getAllPermissionApplications(); 202 let orderSort = this.orderDict(userGrantPermissions); 203 this.allPermissionApplications.sort(this.compare('permission', orderSort)); 204 this.getPermissionLabel() 205 } 206 207 /** 208 * Get the corresponding permission group id according to the permission 209 * @param {String} permission app name id 210 * @return {Number} groupId 211 */ 212 getPermissionGroupByPermission(permission: string) { 213 for (let i = 0; i < permissionGroups.length; i++) { 214 if (permissionGroups[i].permissionName == permission) { 215 return groups[permissionGroups[i].groupId]; 216 } 217 } 218 } 219 220 /** 221 * Get all permission label 222 */ 223 getPermissionLabel() { 224 globalThis.allUserPermissions.forEach(userPermission => { 225 permissionGroups.forEach(permissionInfo => { 226 if(userPermission == permissionInfo.permissionName) { 227 globalThis.context.resourceManager.getString(permissionInfo.label.id).then(val => { 228 globalThis.permissionLabels[userPermission] = val 229 }) 230 } 231 }) 232 }) 233 } 234 235 /** 236 * Get all permission label 237 */ 238 getLabelAndIcon() { 239 const this_ = this 240 setTimeout(function() { 241 globalThis.allBundleInfo.forEach(bundleInfo => { 242 let context = globalThis.context.createBundleContext(bundleInfo.bundleName) 243 this_.updateAppLabel(bundleInfo, context) 244 this_.updateAppIcon(bundleInfo, context) 245 }) 246 }, 100) 247 } 248 249 /** 250 * Get all app permission information 251 */ 252 getAllPermissionApplications() { 253 const this_ = this; 254 for (let i = 0; i < globalThis.allUserPermissions.length; i++) { 255 var permissionGroup = this_.getPermissionGroupByPermission(globalThis.allUserPermissions[i]); 256 var icon: string = permissionGroup.icon; 257 var bundleNames: string[] = []; 258 for (let j = 0; j < globalThis.allBundleInfo.length; j++) { 259 if (globalThis.allBundleInfo[j].permissions.indexOf(globalThis.allUserPermissions[i]) != -1) { 260 bundleNames.push(globalThis.allBundleInfo[j].bundleName); 261 } 262 } 263 var pa: permissionApplications = { 264 'permission': globalThis.allUserPermissions[i], 265 'groupName': permissionGroup.name, 266 'bundleNames': bundleNames, 267 'icon': icon 268 }; 269 this_.allPermissionApplications.push(pa); 270 } 271 } 272 273 /** 274 * Get permission group information 275 */ 276 getAllGroupPermission() { 277 const this_ = this; 278 groups.forEach((item) => { 279 if (item.isShow) { 280 globalThis.allGroups.push(item.name); 281 } 282 }) 283 globalThis.allUserPermissions.forEach(userPermission => { 284 if (globalThis.allGroups.indexOf(groups[permissionGroupIds[userPermission]].name) == -1) { 285 globalThis.allGroups.push(groups[permissionGroupIds[userPermission]].name); 286 } 287 }) 288 // Permission layout 289 for (let i = 0; i < globalThis.allGroups.length; i++) { 290 var permissions: string[] = permissionGroupPermissions[globalThis.allGroups[i]]; 291 var gp: groupPermission = { 292 "group": globalThis.allGroups[i], 293 "permissions": permissions, 294 'groupName': '', 295 'icon': '', 296 'isShow': false 297 }; 298 this_.allGroupPermission.push(gp); 299 } 300 this.allGroupPermission.forEach((ele) => { 301 groups.forEach((item) => { 302 if (ele.group === item.name) { 303 ele.groupName = item.groupName; 304 ele.icon = item.icon; 305 ele.isShow = item.isShow; 306 } 307 }); 308 }) 309 } 310 311 /** 312 * Deduplicate permission information and permission group information 313 * @param {Object} info bundleInfos Application Information 314 */ 315 async deduplicationPermissions(info) { 316 var reqPermissionsLen = info.reqPermissions.length; 317 var reqUserPermissions: string[] = []; 318 var acManager = abilityAccessCtrl.createAtManager() 319 if (reqPermissionsLen > 0) { 320 for (let j = 0; j < info.reqPermissions.length; j++) { 321 var permission = info.reqPermissions[j]; 322 if((info.targetVersion < Constants.API_VERSION_SUPPORT_STAGE) && (permission == FUZZY_LOCATION_PERMISSION)) { 323 continue 324 } 325 if((info.targetVersion >= Constants.API_VERSION_SUPPORT_STAGE) && (permission == PRECISE_LOCATION_PERMISSION) && !info.reqPermissions.includes(FUZZY_LOCATION_PERMISSION)) { 326 continue 327 } 328 try { 329 var flag = await acManager.getPermissionFlags(info.appInfo.accessTokenId, permission) 330 if(flag == Constants.PRE_AUTHORIZATION_NOT_MODIFIED) { 331 continue 332 } 333 } 334 catch(err) { 335 console.log(TAG + 'getPermissionFlags error: ' + JSON.stringify(err)) 336 } 337 if (userGrantPermissions.indexOf(permission) != -1) { 338 reqUserPermissions.push(permission); 339 if (globalThis.allUserPermissions.indexOf(permission) == -1) { 340 globalThis.allUserPermissions.push(permission); 341 } 342 } 343 } 344 } 345 let groupIds = []; 346 for (let i = 0; i < reqUserPermissions.length; i++) { 347 if(groupIds.indexOf(permissionGroupIds[reqUserPermissions[i]]) == -1){ 348 groupIds.push(permissionGroupIds[reqUserPermissions[i]]); 349 } 350 } 351 352 // adapt different api 353 if (info.compatibleVersion >= Constants.API_VERSION_SUPPORT_STAGE) { 354 info.appInfo.iconId = info.hapModuleInfos[0].abilityInfo[0].iconId; 355 } 356 357 var ap: applicationPermissions = { 358 'bundleName': info.name, 359 'api': info.targetVersion, 360 'tokenId': info.appInfo.accessTokenId, 361 'iconId': info.appInfo.iconId, 362 'labelId': info.appInfo.labelId, 363 'permissions': reqUserPermissions, 364 'groupId': groupIds 365 }; 366 globalThis.allBundleInfo.push(ap) 367 } 368 369 /** 370 * Get app name resource 371 * @param {Number} index index of all app permissions array 372 * @param {String} bundleName Package names 373 * @param {String} labelName Application Name 374 */ 375 updateAppLabel(info, context) { 376 context.resourceManager.getString(info.labelId, (error, value) => { 377 info.labelId = value; 378 if (!isNaN(info.labelId)) { 379 info.alphabeticalIndex = ''; 380 } else { 381 info.alphabeticalIndex = makePy(info.labelId)[0].slice(0, 1); // Get the first letter in the returned initials array 382 } 383 }) 384 } 385 386 /** 387 * Get app icon resources 388 * @param {Number} index index of all app permissions array 389 * @param {String} bundleName Package names 390 */ 391 updateAppIcon(info, context) { 392 context.resourceManager.getMediaBase64(info.iconId, (error, value) => { 393 info.iconId = value; 394 }) 395 } 396 397 /** 398 * Lifecycle function, executed when the page is initialized 399 */ 400 aboutToAppear() { 401 console.log(TAG + 'on aboutToAppear, version 1.01'); 402 this.getAllBundlePermissions(); 403 var acManager = abilityAccessCtrl.createAtManager() 404 bundle.getApplicationInfo(Constants.BUNDLE_NAME, 0).then(data => { 405 acManager.grantUserGrantedPermission(data.accessTokenId, "ohos.permission.MICROPHONE", 2) 406 }) 407 globalThis.context.resourceManager.getString($r("app.string.textInput_placeholder").id).then(val => { 408 textInput_placeholder = val 409 }) 410 } 411 412 getPermissionGroup(allGroup, order) { 413 var fixedName: string[] = ['LOCATION', 'CAMERA', 'MICROPHONE'] 414 var extraName: string[] = ['ADS'] 415 var fixedGroup: any[] = [] 416 var extraGroup: any[] = [] 417 var changeGroup: any[] = [] 418 var otherGroup: any[] = [] 419 420 allGroup.forEach(group => { 421 if(fixedName.indexOf(group.group) !== -1) { 422 fixedGroup.push(group) 423 }else if(extraName.includes(group.group)) { 424 extraGroup.push(group) 425 }else if(group.group == 'OTHER') { 426 otherGroup.push(group) 427 }else { 428 changeGroup.push(group) 429 } 430 }) 431 432 if(order == Constants.FIXED_GROUP){ 433 return fixedGroup 434 }else if(order == Constants.CHANGE_GROUP) { 435 return changeGroup 436 }else if(order == Constants.OTHER_GROUP) { 437 return otherGroup 438 }else if(order == Constants.EXTRA_GROUP) { 439 return extraGroup 440 } 441 } 442 443 LoadLabelAndIcon() { 444 const this_ = this 445 setTimeout(function() { this_.ready = true }, 100) 446 return true 447 } 448 449 build() { 450 GridContainer({ gutter: Constants.GUTTER, margin: Constants.GRID_MARGIN }) { 451 Row() { 452 Row() 453 .useSizeType({ 454 xs: { span: Constants.LEFT_XS_SPAN, offset: Constants.LEFT_XS_OFFSET }, 455 sm: { span: Constants.LEFT_SM_SPAN, offset: Constants.LEFT_SM_OFFSET }, 456 md: { span: Constants.LEFT_MD_SPAN, offset: Constants.LEFT_MD_OFFSET }, 457 lg: { span: Constants.LEFT_LG_SPAN, offset: Constants.LEFT_LG_OFFSET } 458 }) 459 .height(Constants.FULL_HEIGHT) 460 Row() { 461 Column() { 462 Row() { 463 backBar( { title: JSON.stringify($r('app.string.authority_management')), recordable: true }) 464 } 465 Row() { 466 Column() { 467 Column() { 468 Stack() { 469 if(this.allGroupPermission.length) { 470 Tabs() { 471 TabContent() { 472 Row() { 473 Column() { 474 Scroll() { 475 Column() { 476 List() { 477 ListItem() { 478 List() { 479 ForEach(this.getPermissionGroup(this.allGroupPermission, Constants.FIXED_GROUP), (item, index) => { 480 this.ListItemLayout(item, index == (this.getPermissionGroup(this.allGroupPermission, Constants.FIXED_GROUP).length - 1)) 481 }, item => item.toString()) 482 }.backgroundColor($r('app.color.default_background_color')) 483 .borderRadius(Constants.BORDER_RADIUS) 484 .padding({ top: Constants.LIST_PADDING_TOP, bottom: Constants.LIST_PADDING_BOTTOM }) 485 .margin({ bottom: Constants.LIST_MARGIN_BOTTOM }) 486 } 487 488 ListItem() { 489 List() { 490 ForEach(this.getPermissionGroup(this.allGroupPermission, Constants.CHANGE_GROUP), (item, index) => { 491 this.ListItemLayout(item, index == (this.getPermissionGroup(this.allGroupPermission, Constants.CHANGE_GROUP).length - 1)) 492 }, item => item.toString()) 493 }.backgroundColor($r('app.color.default_background_color')) 494 .borderRadius(Constants.BORDER_RADIUS) 495 .padding({ top: Constants.LIST_PADDING_TOP, bottom: Constants.LIST_PADDING_BOTTOM }) 496 .margin({ bottom: Constants.LIST_MARGIN_BOTTOM }) 497 } 498 499 if(this.getPermissionGroup(this.allGroupPermission, Constants.EXTRA_GROUP).length) { 500 ListItem() { 501 List() { 502 ForEach(this.getPermissionGroup(this.allGroupPermission, Constants.EXTRA_GROUP), (item, index) => { 503 this.ListItemLayout(item, index == (this.getPermissionGroup(this.allGroupPermission, Constants.EXTRA_GROUP).length - 1)) 504 }, item => item.toString()) 505 }.backgroundColor($r('app.color.default_background_color')) 506 .borderRadius(Constants.BORDER_RADIUS) 507 .padding({ top: Constants.LIST_PADDING_TOP, bottom: Constants.LIST_PADDING_BOTTOM }) 508 .margin({ bottom: Constants.LIST_MARGIN_BOTTOM }) 509 } 510 } 511 512 ListItem() { 513 if(this.LoadLabelAndIcon()) {} 514 List() { 515 ForEach(this.getPermissionGroup(this.allGroupPermission, Constants.OTHER_GROUP), (item) => { 516 this.ListItemLayout(item, Constants.SLICE_END_INDEX) 517 }, item => item.toString()) 518 }.backgroundColor($r('app.color.default_background_color')) 519 .borderRadius(Constants.BORDER_RADIUS) 520 .padding({ top: Constants.LIST_PADDING_TOP, bottom: Constants.LIST_PADDING_BOTTOM }) 521 } 522 }.height(Constants.FULL_HEIGHT) 523 .borderRadius(Constants.BORDER_RADIUS) 524 .clip(true) 525 }.padding({ 526 left: Constants.MANAGEMENT_ROW_PADDING_LEFT, 527 right: Constants.MANAGEMENT_ROW_PADDING_RIGHT, 528 }) 529 }.scrollBar(BarState.Off) 530 .margin({ top: Constants.MANAGEMENT_ROW_PADDING_TOP }) 531 }.width(Constants.FULL_WIDTH) 532 } 533 }.tabBar(this.TabBuilder(0)) 534 TabContent() { 535 applicationItem() 536 }.tabBar(this.TabBuilder(1)) 537 } 538 .barWidth(Constants.BAR_WIDTH) 539 .barMode(BarMode.Fixed) 540 .onChange((index) => { 541 this.currentIndex = index 542 }) 543 }else { 544 LoadingProgress().width(Constants.LOADING_WIDTH) 545 } 546 }.height(Constants.FULL_HEIGHT) 547 } 548 } 549 } 550 .layoutWeight(Constants.LAYOUT_WEIGHT) 551 } 552 } 553 .useSizeType({ 554 xs: { span: Constants.MIDDLE_XS_SPAN, offset: Constants.MIDDLE_XS_OFFSET }, 555 sm: { span: Constants.MIDDLE_SM_SPAN, offset: Constants.MIDDLE_SM_OFFSET }, 556 md: { span: Constants.MIDDLE_MD_SPAN, offset: Constants.MIDDLE_MD_OFFSET }, 557 lg: { span: Constants.MIDDLE_LG_SPAN, offset: Constants.MIDDLE_LG_OFFSET } 558 }) 559 .height(Constants.FULL_HEIGHT) 560 Row() 561 .useSizeType({ 562 xs: { span: Constants.RIGHT_XS_SPAN, offset: Constants.RIGHT_XS_OFFSET }, 563 sm: { span: Constants.RIGHT_SM_SPAN, offset: Constants.RIGHT_SM_OFFSET }, 564 md: { span: Constants.RIGHT_MD_SPAN, offset: Constants.RIGHT_MD_OFFSET }, 565 lg: { span: Constants.RIGHT_LG_SPAN, offset: Constants.RIGHT_LG_OFFSET } 566 }) 567 .height(Constants.FULL_HEIGHT) 568 } 569 .height(Constants.FULL_HEIGHT) 570 .width(Constants.FULL_WIDTH) 571 .backgroundColor($r("sys.color.ohos_id_color_sub_background")) 572 } 573 } 574} 575 576@Component 577struct applicationItem { 578 @State applicationItem: any[] = globalThis.allBundleInfo // application info array 579 @State searchResult: boolean = true // search results 580 581 @Builder ListItemLayout(item, end) { 582 ListItem() { 583 Row() { 584 Column() { 585 Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) { 586 Row() { 587 Image(item.iconId) 588 .customizeImage(Constants.APPLICATION_IMAGE_WIDTH, Constants.APPLICATION_IMAGE_HEIGHT) 589 .margin({ right: Constants.APPLICATION_IMAGE_MARGIN_RIGHT }) 590 Text(item.labelId) 591 .fontSize(Constants.TEXT_MIDDLE_FONT_SIZE) 592 .fontWeight(FontWeight.Medium) 593 .fontColor($r('app.color.label_color')) 594 .flexGrow(Constants.FLEX_GROW) 595 Text(item.groupId.length + '项权限') 596 .fontSize(Constants.TEXT_SMAL_FONT_SIZE) 597 .fontColor($r('app.color.label_color_lighter')) 598 .margin({ right: Constants.APPLICATION_TEXT_MARGIN_RIGHT }) 599 Image($r('app.media.ic_public_arrow_right')) 600 .customizeImage(Constants.IMAGE_WIDTH, Constants.IMAGE_HEIGHT) 601 } 602 .width(Constants.FULL_WIDTH) 603 .height(Constants.AUTHORITY_ROW_HEIGHT) 604 .constraintSize({ minHeight: Constants.AUTHORITY_CONSTRAINTSIZE_MINHEIGHT }) 605 } 606 if (!end) { 607 Row() { 608 Flex() { 609 Column().width(Constants.APPLICATION_TEXT_DECORATION_MARGIN_LEFT) 610 Column() 611 .backgroundColor($r('app.color.text_decoration_color')) 612 .height(Constants.TEXT_DECORATION_HEIGHT) 613 .flexGrow(Constants.FLEX_GROW) 614 } 615 } 616 } 617 }.onClick(() => { 618 globalThis.applicationInfo = item 619 router.pushUrl({ url: 'pages/application-secondary' }); 620 }) 621 } 622 }.padding({ 623 left: Constants.DEFAULT_PADDING_START, 624 right: Constants.DEFAULT_PADDING_END 625 }) 626 } 627 628 build() { 629 Column() { 630 Row() { 631 textInput({ 632 placeholder: String(textInput_placeholder), 633 applicationItem: $applicationItem, 634 searchResult: $searchResult 635 }) 636 }.padding({ 637 left: Constants.APPLICATION_TEXTINPUT_PADDING_LEFT, 638 top: Constants.APPLICATION_TEXTINPUT_PADDING_TOP, 639 right: Constants.APPLICATION_TEXTINPUT_PADDING_RIGHT 640 }) 641 Row() { 642 Flex({ alignItems: ItemAlign.Start }) { 643 Column() { 644 Column() { 645 if (!this.applicationItem.length) { 646 Row() { 647 Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) { 648 Image($r('app.media.searchnoresult')) 649 .customizeImage(Constants.SEARCHNORESULT_IMAGE_WIDTH, Constants.SEARCHNORESULT_IMAGE_HEIGHT) 650 } 651 }.margin({ top: Constants.MANAGEMENT_ROW_MARGIN_TOP }) 652 .padding({ left: Constants.MANAGEMENT_ROW_PADDING_LEFT }) 653 } else { 654 Row() { 655 Scroll() { 656 List() { 657 ForEach(this.applicationItem, (item, index) => { 658 this.ListItemLayout(item, index == (this.applicationItem.length - 1)) 659 }, item => item.toString()) 660 }.backgroundColor($r('app.color.default_background_color')) 661 .borderRadius(Constants.BORDER_RADIUS) 662 .padding({ top: Constants.LIST_PADDING_TOP, bottom: Constants.LIST_PADDING_BOTTOM }) 663 }.scrollBar(BarState.Off) 664 }.margin({ left: Constants.MANAGEMENT_ROW_PADDING_LEFT }) 665 .borderRadius(Constants.BORDER_RADIUS) 666 .clip(true) 667 } 668 }.backgroundColor($r('app.color.background_color')) 669 .height(Constants.FULL_HEIGHT) 670 }.margin({ top: Constants.MANAGEMENT_ROW_MARGIN_TOP, bottom: Constants.APPLICATION_LIST_MARGIN_BOTTOM }) 671 Column() { 672 alphabetIndexerComponent({ applicationItem: $applicationItem }) 673 }.margin({ top: Constants.APPLICATION_ALPHABETINDEX_MARGIN_TOP }) 674 .width(Constants.APPLICATION_ALPHABETINDEX_WIDTH) 675 } 676 } 677 } 678 } 679} 680