1/* 2 * Copyright (c) 2021-2023 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 abilityAccessCtrl, { Permissions } from '@ohos.abilityAccessCtrl'; 21import audio from '@ohos.multimedia.audio' 22import camera from '@ohos.multimedia.camera' 23import display from '@ohos.display'; 24import common from '@ohos.app.ability.common'; 25import { groups, userGrantPermissions, globalGroup, permissionGroups, showSubPermissionsGroup } from '../common/model/permissionGroup'; 26import { Log, indexValue, getPermissionGroupByName, getGroupIdByPermission, addLocalTag, sortByName } from '../common/utils/utils'; 27import { AppInfo, PermissionApplications, GroupPermission, GroupInfo } from '../common/utils/typedef'; 28import { GlobalContext } from '../common/utils/globalContext'; 29import Constants from '../common/utils/constant'; 30import bundleManager from '@ohos.bundle.bundleManager'; 31 32const FUZZY_LOCATION_PERMISSION = 'ohos.permission.APPROXIMATELY_LOCATION'; 33const PRECISE_LOCATION_PERMISSION = 'ohos.permission.LOCATION'; 34let storage = LocalStorage.getShared(); 35 36@Extend(Image)function customizeImage(width: number, height: number) { 37 .objectFit(ImageFit.Contain) 38 .width(width) 39 .height(height) 40 .draggable(false) 41}; 42 43@Entry(storage) 44@Component 45struct authorityManagementPage { 46 @Builder ListItemLayout(item: GroupPermission) { 47 ListItem() { 48 Row() { 49 Column() { 50 Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) { 51 Row() { 52 Image(item.icon) 53 .fillColor($r('sys.color.icon_secondary')) 54 .customizeImage(Constants.MANAGEMENT_IMAGE_WIDTH, Constants.MANAGEMENT_IMAGE_HEIGHT) 55 .margin({ right: Constants.MANAGEMENT_IMAGE_MARGIN_RIGHT }) 56 Text(item.groupName) 57 .fontSize(Constants.TEXT_MIDDLE_FONT_SIZE) 58 .fontWeight(FontWeight.Medium) 59 .fontColor($r('sys.color.font_primary')) 60 .flexGrow(Constants.FLEX_GROW) 61 Image($r('app.media.ic_public_arrow_right')) 62 .fillColor($r('sys.color.icon_tertiary')) 63 .customizeImage(Constants.IMAGE_WIDTH, Constants.IMAGE_HEIGHT) 64 } 65 .width(Constants.FULL_WIDTH) 66 .height(Constants.MANAGEMENT_ROW_HEIGHT) 67 } 68 }.onClick(() => { 69 if (item.group === 'OTHER' || showSubPermissionsGroup.indexOf(item.group) !== -1) { 70 router.pushUrl({ 71 url: 'pages/authority-secondary', 72 params: { list: this.allPermissionApplications, backTitle: item.groupName, group: item.group } 73 }) 74 } else { 75 let dataList = this.allPermissionApplications.filter((ele) => { 76 return ele.groupName === item.group; 77 }) 78 79 GlobalContext.store('currentPermissionGroup', item.group); 80 if (globalGroup.indexOf(item.group) == -1) { 81 router.pushUrl({ 82 url: 'pages/authority-tertiary-groups', 83 params: { list: dataList, backTitle: item.groupName } 84 }) 85 } else { 86 if (item.group == 'MICROPHONE') { 87 let audioManager = audio.getAudioManager(); 88 let audioVolumeManager = audioManager.getVolumeManager(); 89 let groupId = audio.DEFAULT_VOLUME_GROUP_ID; 90 audioVolumeManager.getVolumeGroupManager(groupId).then(audioVolumeGroupManager => { 91 let muteState = audioVolumeGroupManager.isPersistentMicMute(); 92 GlobalContext.store('isMuteSupported', true); 93 router.pushUrl({ 94 url: 'pages/authority-tertiary-groups', 95 params: { list: dataList, backTitle: item.groupName, globalIsOn: !muteState } 96 }) 97 }) 98 } else { 99 let cameraManager = camera.getCameraManager(GlobalContext.load('context')); 100 let mute = cameraManager.isCameraMuted(); 101 GlobalContext.store('isMuteSupported', cameraManager.isCameraMuteSupported()); 102 router.pushUrl({ 103 url: 'pages/authority-tertiary-groups', 104 params: { list: dataList, backTitle: item.groupName, globalIsOn: !mute } 105 }) 106 } 107 } 108 } 109 }) 110 } 111 }.padding({ left: $r('sys.float.ohos_id_card_margin_start'), right: $r('sys.float.ohos_id_card_margin_end') }) 112 .borderRadius($r('sys.float.ohos_id_corner_radius_default_l')) 113 .linearGradient((this.isTouch === item.group) ? { 114 angle: 90, 115 direction: GradientDirection.Right, 116 colors: [['#DCEAF9', 0.0], ['#FAFAFA', 1.0]] 117 } : { 118 angle: 90, 119 direction: GradientDirection.Right, 120 colors: [[$r('sys.color.comp_background_list_card'), 1], [$r('sys.color.comp_background_list_card'), 1]] 121 }) 122 .onTouch(event => { 123 if (event === undefined) { 124 return; 125 } 126 if (event.type === TouchType.Down) { 127 this.isTouch = item.group; 128 } 129 if (event.type === TouchType.Up) { 130 this.isTouch = ''; 131 } 132 }) 133 } 134 135 private context = getContext(this) as common.UIAbilityContext; 136 @LocalStorageLink('initialGroups') initialGroups: bundleManager.BundleInfo[] = []; 137 @State allPermissionApplications: PermissionApplications [] = []; // All app permissions 138 @State allGroupPermission: GroupPermission[] = []; // All group permissions 139 @State allUserPermissions: Permissions[] = []; 140 @State allBundleInfo: AppInfo[] = []; 141 @State allGroups: string[] = []; 142 @State currentIndex: number = 0; 143 @State isTouch: string = ''; 144 @State isVertical: boolean = true; 145 @Builder TabBuilder(index: number) { 146 Flex({ 147 alignItems: index ? ItemAlign.Start : ItemAlign.End, 148 justifyContent: FlexAlign.Center, direction: FlexDirection.Column 149 }) { 150 Text(index ? $r('app.string.application') : $r('app.string.permission')) 151 .fontSize(Constants.TEXT_MIDDLE_FONT_SIZE) 152 .fontColor( 153 this.currentIndex == index ? 154 $r('sys.color.ohos_id_color_subtab_text_on') : 155 $r('sys.color.icon_secondary') 156 ) 157 .fontWeight(this.currentIndex == index ? FontWeight.Bold : FontWeight.Regular) 158 .lineHeight(Constants.TEXT_LINE_HEIGHT) 159 .baselineOffset(Constants.TAB_DECORATION_POSITION_Y) 160 if (this.currentIndex == index) { 161 Text(index ? $r('app.string.application') : $r('app.string.permission')) 162 .fontSize(Constants.TEXT_MIDDLE_FONT_SIZE) 163 .fontWeight(FontWeight.Bold) 164 .lineHeight(Constants.TAB_LINE_HEIGHT) 165 .height(Constants.TAB_DECORATION_HEIGHT) 166 .fontColor($r('sys.color.ohos_id_color_subtab_text_on')) 167 .backgroundColor($r('sys.color.ohos_id_color_subtab_text_on')) 168 } 169 }.height(Constants.TAB_HEIGHT) 170 .width(Constants.FULL_WIDTH) 171 .padding({ left: this.isVertical ? Constants.TAB_INNER_PADDING : Constants.DEFAULT_PADDING_START, 172 right: this.isVertical ? Constants.TAB_INNER_PADDING : Constants.DEFAULT_PADDING_END }) 173 } 174 175 /** 176 * Get all app permission information 177 */ 178 async getAllBundlePermissions() { 179 for (let i = 0; i < this.initialGroups.length; i++) { 180 await this.deduplicationPermissions(this.initialGroups[i]); 181 } 182 this.getAllGroupPermission(); 183 this.getAllPermissionApplications(); 184 this.getLabelAndIcon(); 185 GlobalContext.store('allBundleInfo', this.allBundleInfo); 186 } 187 188 /** 189 * Get the corresponding permission group id according to the permission 190 * @param {String} permission app name id 191 * @return {Number} groupId 192 */ 193 getPermissionGroupByPermission(permission: string): GroupInfo { 194 for (let i = 0; i < permissionGroups.length; i++) { 195 if (permissionGroups[i].permissionName == permission) { 196 return groups[permissionGroups[i].groupId]; 197 } 198 } 199 return groups[0]; 200 } 201 202 /** 203 * Get all permission label 204 */ 205 getLabelAndIcon() { 206 this.allBundleInfo.forEach((bundleInfo: AppInfo) => { 207 this.updateAppLabel(bundleInfo); 208 this.updateAppIcon(bundleInfo); 209 }) 210 } 211 212 /** 213 * Get all app permission information 214 */ 215 getAllPermissionApplications() { 216 for (let i = 0; i < this.allUserPermissions.length; i++) { 217 let permission: Permissions = this.allUserPermissions[i]; 218 let permissionGroup: GroupInfo = this.getPermissionGroupByPermission(permission); 219 let icon: ResourceStr = permissionGroup.icon; 220 let bundleNames: string[] = []; 221 for (let j = 0; j < this.allBundleInfo.length; j++) { 222 if (this.allBundleInfo[j].permissions.indexOf(permission) != -1) { 223 bundleNames.push(this.allBundleInfo[j].bundleName); 224 } 225 } 226 let pa: PermissionApplications = new PermissionApplications(permission, permissionGroup.name, bundleNames, icon); 227 this.allPermissionApplications.push(pa); 228 } 229 } 230 231 /** 232 * Get permission group information 233 */ 234 getAllGroupPermission() { 235 groups.forEach((item) => { 236 if (item.isShow) { 237 this.allGroups.push(item.name); 238 } 239 }) 240 this.allUserPermissions.forEach((userPermission: Permissions) => { 241 let groupId = getGroupIdByPermission(userPermission) 242 if (this.allGroups.indexOf(groups[groupId].name) == -1) { 243 this.allGroups.push(groups[groupId].name); 244 } 245 }) 246 // Permission layout 247 for (let i = 0; i < this.allGroups.length; i++) { 248 let group = getPermissionGroupByName(this.allGroups[i]); 249 let gp: GroupPermission = new GroupPermission( 250 this.allGroups[i], group.permissions, group.groupName, group.icon, group.isShow 251 ); 252 this.allGroupPermission.push(gp); 253 } 254 } 255 256 /** 257 * Deduplicate permission information and permission group information 258 * @param {Object} info bundleInfos Application Information 259 */ 260 async deduplicationPermissions(info: bundleManager.BundleInfo) { 261 Log.info('allBundleInfo start: ' + info.name); 262 let reqPermissions: Permissions[] = []; 263 info.reqPermissionDetails.forEach(item => { 264 reqPermissions.push(item.name as Permissions); 265 }) 266 let reqPermissionsLen = reqPermissions.length; 267 let reqUserPermissions: Permissions[] = []; 268 let acManager = abilityAccessCtrl.createAtManager() 269 if (reqPermissionsLen > 0) { 270 for (let j = 0; j < reqPermissions.length; j++) { 271 let permission = reqPermissions[j]; 272 if ((permission == PRECISE_LOCATION_PERMISSION) && !reqPermissions.includes(FUZZY_LOCATION_PERMISSION)) { 273 continue; 274 } 275 try { 276 let flag = await acManager.getPermissionFlags(info.appInfo.accessTokenId, permission); 277 if (flag == Constants.PERMISSION_SYSTEM_FIXED) { 278 continue; 279 } 280 } catch (err) { 281 Log.error('getPermissionFlags error: ' + JSON.stringify(err)); 282 } 283 if (userGrantPermissions.indexOf(permission) != -1) { 284 reqUserPermissions.push(permission); 285 if (this.allUserPermissions.indexOf(permission) == -1) { 286 this.allUserPermissions.push(permission); 287 } 288 } 289 } 290 } 291 this.getAllBundleInfo(info, reqUserPermissions); 292 } 293 294 getAllBundleInfo(info: bundleManager.BundleInfo, reqUserPermissions: Permissions[]) { 295 let groupIds: number[] = []; 296 for (let i = 0; i < reqUserPermissions.length; i++) { 297 let groupId = getGroupIdByPermission(reqUserPermissions[i]) 298 if (groupIds.indexOf(groupId) == -1) { 299 groupIds.push(groupId); 300 } 301 } 302 303 let ap: AppInfo = new AppInfo( 304 info.name, 305 info.targetVersion, 306 info.appInfo.accessTokenId, 307 '', 308 info.appInfo.iconId, 309 info.appInfo.iconResource, 310 info.appInfo.label, 311 info.appInfo.labelId, 312 info.appInfo.labelResource, 313 reqUserPermissions, 314 groupIds, 315 '', 316 '', 317 '' 318 ); 319 Log.info('allBundleInfo.push: ' + info.name); 320 this.allBundleInfo.push(ap); 321 } 322 323 /** 324 * Get app name resource 325 * @param {Number} index index of all app permissions array 326 * @param {String} bundleName Package names 327 * @param {String} labelName Application Name 328 */ 329 async updateAppLabel(info: AppInfo) { 330 Log.info( 331 'bundleName: ' + info.bundleName + 332 ` labelResource: ` + JSON.stringify(info.labelResource) + 333 ' labelId: ' + info.labelId 334 ); 335 336 try { 337 if (info.labelResource.id !== 0) { 338 info.label = await this.context.resourceManager.getStringValue(info.labelResource); 339 } else { 340 let resourceManager = this.context.createBundleContext(info.bundleName).resourceManager; 341 info.label = await resourceManager.getStringValue(info.labelId); 342 } 343 } catch (error) { 344 Log.error('getStringValue promise error is ' + error); 345 } 346 addLocalTag(info); 347 } 348 349 /** 350 * Get app icon resources 351 * @param {Number} index index of all app permissions array 352 * @param {String} bundleName Package names 353 */ 354 async updateAppIcon(info: AppInfo) { 355 Log.info( 356 'bundleName: ' + info.bundleName + 357 ` iconResource: ` + JSON.stringify(info.iconResource) + 358 ' iconId: ' + info.iconId 359 ); 360 361 try { 362 if (info.iconResource.id !== 0) { 363 let iconDescriptor = this.context.resourceManager.getDrawableDescriptor(info.iconResource); 364 info.icon = iconDescriptor?.getPixelMap(); 365 } else { 366 let resourceManager = this.context.createBundleContext(info.bundleName).resourceManager; 367 let iconDescriptor = resourceManager.getDrawableDescriptor(info.iconId); 368 info.icon = iconDescriptor?.getPixelMap(); 369 } 370 } catch (error) { 371 Log.error(`getDrawableDescriptor failed, error code: ${error.code}, message: ${error.message}.`); 372 } 373 374 if (!info.icon) { 375 info.icon = $r('app.media.icon'); 376 } 377 } 378 379 /** 380 * Lifecycle function, executed when the page is initialized 381 */ 382 aboutToAppear() { 383 this.getAllBundlePermissions(); 384 let dis = display.getDefaultDisplaySync(); 385 this.isVertical = dis.height > dis.width ? true : false; 386 GlobalContext.store('isVertical', dis.height > dis.width ? true : false); 387 } 388 389 getPermissionGroup(allGroup: GroupPermission[], order: number): GroupPermission[] { 390 let fixedName: string[] = ['LOCATION', 'CAMERA', 'MICROPHONE']; 391 let extraName: string[] = ['ADS']; 392 let fixedGroup: GroupPermission[] = []; 393 let extraGroup: GroupPermission[] = []; 394 let changeGroup: GroupPermission[] = []; 395 let otherGroup: GroupPermission[] = []; 396 397 allGroup.forEach(group => { 398 if (fixedName.indexOf(group.group) !== -1) { 399 fixedGroup.push(group); 400 } else if (extraName.includes(group.group)) { 401 extraGroup.push(group); 402 } else if (group.group == 'OTHER') { 403 otherGroup.push(group); 404 } else { 405 changeGroup.push(group); 406 } 407 }) 408 409 if (order == Constants.FIXED_GROUP) { 410 return fixedGroup; 411 } else if (order == Constants.CHANGE_GROUP) { 412 return changeGroup; 413 } else if (order == Constants.OTHER_GROUP) { 414 return otherGroup; 415 } else if (order == Constants.EXTRA_GROUP) { 416 return extraGroup; 417 } 418 return []; 419 } 420 421 build() { 422 GridRow({ gutter: Constants.GUTTER, columns: { 423 xs: Constants.XS_COLUMNS, sm: Constants.SM_COLUMNS, md: Constants.MD_COLUMNS, lg: Constants.LG_COLUMNS } }) { 424 GridCol({ 425 span: { xs: Constants.XS_SPAN, sm: Constants.SM_SPAN, md: Constants.MD_SPAN, lg: Constants.LG_SPAN }, 426 offset: { xs: Constants.XS_OFFSET, sm: Constants.SM_OFFSET, md: Constants.MD_OFFSET, lg: Constants.LG_OFFSET } 427 }) { 428 Row() { 429 Column() { 430 Row() { 431 backBar( { title: JSON.stringify($r('app.string.permission_manager')), recordable: true }) 432 } 433 Row() { 434 Column() { 435 Column() { 436 Stack() { 437 if (this.allGroupPermission.length) { 438 Tabs() { 439 TabContent() { 440 Row() { 441 Column() { 442 Scroll() { 443 Column() { 444 List() { 445 ListItem() { 446 List() { 447 ForEach( 448 this.getPermissionGroup(this.allGroupPermission, Constants.FIXED_GROUP), 449 (item: GroupPermission) => { this.ListItemLayout(item) }, 450 (item: GroupPermission) => JSON.stringify(item) 451 ) 452 }.backgroundColor($r('sys.color.comp_background_list_card')) 453 .borderRadius($r('sys.float.ohos_id_corner_radius_card')) 454 .padding(Constants.LIST_PADDING_TOP) 455 .margin({ bottom: Constants.LIST_MARGIN_BOTTOM }) 456 .divider({ 457 strokeWidth: Constants.DIVIDER, 458 color: $r('sys.color.comp_divider'), 459 startMargin: Constants.DIVIDER_MARGIN_RIGHT_PERMISSION, 460 endMargin: Constants.DEFAULT_MARGIN_END 461 }) 462 } 463 464 ListItem() { 465 List() { 466 ForEach( 467 this.getPermissionGroup(this.allGroupPermission, Constants.CHANGE_GROUP), 468 (item: GroupPermission) => { this.ListItemLayout(item) }, 469 (item: GroupPermission) => JSON.stringify(item) 470 ) 471 }.backgroundColor($r('sys.color.comp_background_list_card')) 472 .borderRadius($r('sys.float.ohos_id_corner_radius_card')) 473 .padding(Constants.LIST_PADDING_TOP) 474 .margin({ bottom: Constants.LIST_MARGIN_BOTTOM }) 475 .divider({ 476 strokeWidth: Constants.DIVIDER, 477 color: $r('sys.color.comp_divider'), 478 startMargin: Constants.DIVIDER_MARGIN_RIGHT_PERMISSION, 479 endMargin: Constants.DEFAULT_MARGIN_END 480 }) 481 } 482 483 if ( 484 this.getPermissionGroup(this.allGroupPermission, Constants.EXTRA_GROUP).length 485 ) { 486 ListItem() { 487 List() { 488 ForEach( 489 this.getPermissionGroup(this.allGroupPermission, Constants.EXTRA_GROUP), 490 (item: GroupPermission) => { this.ListItemLayout(item) }, 491 (item: GroupPermission) => JSON.stringify(item) 492 ) 493 }.backgroundColor($r('sys.color.comp_background_list_card')) 494 .borderRadius($r('sys.float.ohos_id_corner_radius_card')) 495 .padding(Constants.LIST_PADDING_TOP) 496 .margin({ bottom: Constants.LIST_MARGIN_BOTTOM }) 497 .divider({ 498 strokeWidth: Constants.DIVIDER, 499 color: $r('sys.color.comp_divider'), 500 startMargin: Constants.DIVIDER_MARGIN_RIGHT_PERMISSION, 501 endMargin: Constants.DEFAULT_MARGIN_END 502 }) 503 } 504 } 505 506 ListItem() { 507 List() { 508 ForEach( 509 this.getPermissionGroup(this.allGroupPermission, Constants.OTHER_GROUP), 510 (item: GroupPermission) => { this.ListItemLayout(item) }, 511 (item: GroupPermission) => JSON.stringify(item) 512 ) 513 }.backgroundColor($r('sys.color.comp_background_list_card')) 514 .borderRadius($r('sys.float.ohos_id_corner_radius_card')) 515 .padding(Constants.LIST_PADDING_TOP) 516 .divider({ 517 strokeWidth: Constants.DIVIDER, 518 color: $r('sys.color.comp_divider'), 519 startMargin: Constants.DIVIDER_MARGIN_RIGHT_PERMISSION, 520 endMargin: Constants.DEFAULT_MARGIN_END 521 }) 522 }.margin({ bottom: Constants.AUTHORITY_ROW_MARGIN_BOTTOM }) 523 }.height(Constants.FULL_HEIGHT) 524 .borderRadius($r('sys.float.ohos_id_corner_radius_card')) 525 .clip(true) 526 }.padding({ 527 left: Constants.MANAGEMENT_ROW_PADDING_LEFT, 528 right: Constants.MANAGEMENT_ROW_PADDING_RIGHT, 529 }) 530 }.scrollBar(BarState.Off) 531 .margin({ top: Constants.MANAGEMENT_ROW_PADDING_TOP }) 532 }.width(Constants.FULL_WIDTH) 533 } 534 }.tabBar(this.TabBuilder(0)) 535 TabContent() { 536 applicationItem() 537 }.tabBar(this.TabBuilder(1)) 538 } 539 .barMode(BarMode.Fixed) 540 .barWidth(Constants.BAR_WIDTH) 541 .onChange((index) => { 542 this.currentIndex = index 543 }) 544 } else { 545 LoadingProgress().width(Constants.LOADING_WIDTH) 546 } 547 }.height(Constants.FULL_HEIGHT) 548 } 549 } 550 } 551 .layoutWeight(Constants.LAYOUT_WEIGHT) 552 } 553 } 554 .height(Constants.FULL_HEIGHT) 555 .width(Constants.FULL_WIDTH) 556 .backgroundColor($r('sys.color.background_secondary')) 557 } 558 }.backgroundColor($r('sys.color.background_secondary')) 559 } 560} 561 562@Component 563struct applicationItem { 564 @State applicationItem: AppInfo[] = GlobalContext.load('allBundleInfo'); // application info array 565 @State searchResult: boolean = true; // search results 566 @State selectedIndex: number = 0; 567 @State isTouch: string = ''; 568 scroller: Scroller = new Scroller(); 569 570 @Builder ListItemLayout(item: AppInfo) { 571 ListItem() { 572 Row() { 573 Column() { 574 Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) { 575 Row() { 576 Image(item.icon) 577 .customizeImage(Constants.APPLICATION_IMAGE_WIDTH, Constants.APPLICATION_IMAGE_HEIGHT) 578 .margin({ right: Constants.APPLICATION_IMAGE_MARGIN_RIGHT }) 579 Text(item.label) 580 .width(Constants.OFFSET) 581 .maxLines(Constants.MAXIMUM_HEADER_LINES) 582 .textOverflow({ overflow: TextOverflow.Ellipsis }) 583 .fontSize(Constants.TEXT_MIDDLE_FONT_SIZE) 584 .fontWeight(FontWeight.Medium) 585 .fontColor($r('sys.color.font_primary')) 586 .flexGrow(Constants.FLEX_GROW) 587 Text(String(item.groupId.length)) 588 .fontSize(Constants.TEXT_SMALL_FONT_SIZE) 589 .fontColor($r('sys.color.font_secondary')) 590 Text($r('app.string.right')) 591 .fontSize(Constants.TEXT_SMALL_FONT_SIZE) 592 .fontColor($r('sys.color.font_secondary')) 593 .margin({ right: Constants.APPLICATION_TEXT_MARGIN_RIGHT }) 594 Image($r('app.media.ic_public_arrow_right')) 595 .fillColor($r('sys.color.icon_tertiary')) 596 .customizeImage(Constants.IMAGE_WIDTH, Constants.IMAGE_HEIGHT) 597 } 598 .width(Constants.FULL_WIDTH) 599 .height(Constants.AUTHORITY_ROW_HEIGHT) 600 .constraintSize({ minHeight: Constants.AUTHORITY_CONSTRAINTSIZE_MINHEIGHT }) 601 } 602 }.onClick(() => { 603 GlobalContext.store('applicationInfo', item); 604 router.pushUrl({ url: 'pages/application-secondary' }); 605 }) 606 } 607 }.padding({ left: $r('sys.float.ohos_id_card_margin_start'), right: $r('sys.float.ohos_id_card_margin_end') }) 608 .borderRadius($r('sys.float.ohos_id_corner_radius_default_l')) 609 .linearGradient((this.isTouch === item.bundleName) ? { 610 angle: 90, 611 direction: GradientDirection.Right, 612 colors: [['#DCEAF9', 0.0], ['#FAFAFA', 1.0]] 613 } : { 614 angle: 90, 615 direction: GradientDirection.Right, 616 colors: [[$r('sys.color.comp_background_list_card'), 1], [$r('sys.color.comp_background_list_card'), 1]] 617 }) 618 .onTouch(event => { 619 if (event === undefined) { 620 return; 621 } 622 if (event.type === TouchType.Down) { 623 this.isTouch = item.bundleName; 624 } 625 if (event.type === TouchType.Up) { 626 this.isTouch = ''; 627 } 628 }) 629 } 630 631 build() { 632 Column() { 633 Row() { 634 textInput({ 635 applicationItem: $applicationItem, 636 searchResult: $searchResult 637 }) 638 }.padding({ 639 left: Constants.APPLICATION_TEXTINPUT_PADDING_LEFT, 640 top: Constants.APPLICATION_TEXTINPUT_PADDING_TOP, 641 right: Constants.APPLICATION_TEXTINPUT_PADDING_RIGHT 642 }) 643 Row() { 644 Flex({ alignItems: ItemAlign.Start }) { 645 Column() { 646 Column() { 647 if (!this.applicationItem.length) { 648 Row() { 649 Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) { 650 Image($r('app.media.searchnoresult')) 651 .customizeImage(Constants.SEARCHNORESULT_IMAGE_WIDTH, Constants.SEARCHNORESULT_IMAGE_HEIGHT) 652 } 653 }.margin({ top: Constants.MANAGEMENT_ROW_MARGIN_TOP }) 654 .padding({ left: Constants.MANAGEMENT_ROW_PADDING_LEFT }) 655 } else { 656 Row() { 657 List({ scroller: this.scroller }) { 658 ForEach(sortByName(this.applicationItem), (item: AppInfo) => { 659 this.ListItemLayout(item) 660 }, (item: AppInfo) => JSON.stringify(item)) 661 }.backgroundColor($r('sys.color.comp_background_list_card')) 662 .borderRadius($r('sys.float.ohos_id_corner_radius_card')) 663 .padding(Constants.LIST_PADDING_TOP) 664 .divider({ 665 strokeWidth: Constants.DIVIDER, 666 color: $r('sys.color.comp_divider'), 667 startMargin: Constants.DIVIDER_MARGIN_RIGHT_APPLICATION, 668 endMargin: Constants.DEFAULT_MARGIN_END 669 }) 670 .onScrollIndex((start, end) => { 671 GlobalContext.getContext().set('scroller', this.scroller); 672 if (this.applicationItem.length > 0) { 673 let alphabeticalIndex = sortByName(this.applicationItem)[start].indexTag; 674 let index = indexValue.indexOf(alphabeticalIndex); 675 this.selectedIndex = index >= 0 ? index : 0; 676 } 677 }) 678 }.margin({ left: Constants.MANAGEMENT_ROW_PADDING_LEFT }) 679 .borderRadius($r('sys.float.ohos_id_corner_radius_card')) 680 .clip(true) 681 } 682 }.height(Constants.FULL_HEIGHT) 683 }.margin({ top: Constants.MANAGEMENT_ROW_MARGIN_TOP, bottom: Constants.APPLICATION_LIST_MARGIN_BOTTOM }) 684 Column() { 685 alphabetIndexerComponent({ applicationItem: $applicationItem, index: $selectedIndex }) 686 } 687 .margin({ 688 top: Constants.APPLICATION_ALPHABETINDEX_MARGIN_TOP, 689 bottom: Constants.APPLICATION_LIST_MARGIN_BOTTOM 690 }) 691 .width(Constants.APPLICATION_ALPHABETINDEX_WIDTH) 692 } 693 } 694 } 695 } 696}