1/* 2 * Copyright (c) 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 router from '@ohos.router'; 17import prompt from '@system.prompt'; 18import Curves from '@ohos.curves'; 19import { MenuOperation } from '@ohos/common'; 20import { 21 Action, 22 AddMenuOperation, 23 AlbumDefine, 24 AlbumInfo, 25 BatchDeleteMenuOperation, 26 BatchRemoveMenuOperation, 27 BroadCast, 28 BroadCastConstants, 29 BroadCastManager, 30 BrowserConstants, 31 CommonObserverCallback, 32 Constants, 33 DeleteMenuOperation, 34 ImageUtil, 35 JumpSourceToMain, 36 Log, 37 MediaDataSource, 38 MediaItem, 39 MediaObserver, 40 MediaOperationType, 41 MenuContext, 42 MenuOperationFactory, 43 MoveMenuOperation, 44 RemoveMenuOperation, 45 ScreenManager, 46 SelectManager, 47 ShareMenuOperation, 48 TraceControllerUtils, 49 UiUtil, 50 UserFileManagerAccess, 51 ViewData 52} from '@ohos/common'; 53import { 54 BrowserController, 55 CustomDialogView, 56 GridScrollBar, 57 ImageGridItemComponent, 58 NoPhotoComponent 59} from '@ohos/common/CommonComponents'; 60import { RecoverMenuOperation } from '@ohos/browser'; 61import { 62 BatchRecoverMenuOperation, 63 ClearRecycleMenuOperation, 64 PhotoGridPageActionBar, 65 PhotoGridPageToolBar 66} from '@ohos/browser/BrowserComponents'; 67 68 69const TAG: string = 'PhotoGridView'; 70AppStorage.SetOrCreate('PhotoGridPageIndex', Constants.INVALID); 71 72// Album View 73@Component 74export struct PhotoGridView { 75 @State isShowScrollBar: boolean = false; 76 @Provide isEmpty: boolean = false; 77 @State gridRowCount: number = 0; 78 @Consume @Watch('updateRightClickMenuList') isSelectedMode: boolean; 79 @Provide isAllSelected: boolean = false; 80 @State totalSelectedCount: number = 0; 81 @StorageLink('isHorizontal') isHorizontal: boolean = ScreenManager.getInstance().isHorizontal(); 82 @Provide broadCast: BroadCast = new BroadCast(); 83 @Consume isShow: boolean; 84 @Provide isShowBar: boolean = true; 85 @Provide moreMenuList: Array<Action> = new Array<Action>(); 86 @Provide rightClickMenuList: Array<Action> = new Array<Action>(); 87 @StorageLink('PhotoGridPageIndex') @Watch('onIndexChange') PhotoGridPageIndex: number = Constants.INVALID; 88 @StorageLink('isSplitMode') isSplitMode: boolean = ScreenManager.getInstance().isSplitMode(); 89 @StorageLink('leftBlank') leftBlank: number[] 90 = [0, ScreenManager.getInstance().getStatusBarHeight(), 0, ScreenManager.getInstance().getNaviBarHeight()]; 91 @Prop @Watch('onPageChanged') pageStatus: boolean = false; 92 @State gridItemWidth: number = 0; 93 @StorageLink('photoGridActionBarOpacity') photoGridActionBarOpacity: number = 0; 94 @StorageLink('photoGridViewOpacity') photoGridViewOpacity: number = 0; 95 albumInfo: AlbumInfo = new AlbumInfo(); 96 title: string = ''; 97 deviceName: string = ''; 98 dataSource: MediaDataSource = new MediaDataSource(Constants.DEFAULT_SLIDING_WIN_SIZE); 99 scroller: Scroller = new Scroller(); 100 isDataFreeze = false; 101 mSelectManager = new SelectManager(); 102 isActive = false; 103 isDistributedAlbum = false; 104 deleteMode: boolean = false; 105 routerStart = false; 106 isFromFACard = false; 107 @StorageLink('placeholderIndex') @Watch('onPlaceholderChanged') placeholderIndex: number = -1; 108 @Provide hidePopup: boolean = false; 109 @ObjectLink browserController: BrowserController; 110 private dataObserver: CommonObserverCallback = new CommonObserverCallback(this); 111 private appBroadCast: BroadCast = BroadCastManager.getInstance().getBroadCast(); 112 // 选择模式下,鼠标对着未勾选项按右键弹框时,移动和复制菜单点击事件的标识位 113 private isMvOrCpSeparatesItem: boolean = false; 114 private mvOrCpSeparatesItem: MediaItem = new MediaItem(); 115 private photoTotalCount: number = 0; 116 private params: Params | null = null; 117 private scrollIndex: number = 0; 118 private onWindowSizeChangeCallBack: Function = () => { 119 // 后续phone缩略图支持横竖屏后再放开 120 // this.initGridRowCount; 121 } 122 private selectFunc: Function = (position: number, key: string, value: boolean, callback: Function): void => this.select(position, key, value, callback); 123 private jumpPhotoBrowserFunc: Function = (name: string, item: MediaItem, geometryTapIndex: number, geometryTransitionString: string): void => 124 this.jumpPhotoBrowser(name, item, geometryTapIndex, geometryTransitionString); 125 private jumpThirdPhotoBrowserFunc: Function = (name: string, item: MediaItem, geometryTapIndex: number, geometryTransitionString: string): void => 126 this.jumpThirdPhotoBrowser(name, item, geometryTapIndex, geometryTransitionString); 127 private onLoadingFinishedFunc: Function = (size: number): void => this.onLoadingFinished(size); 128 private onDataReloadedFunc: Function = (): void => this.onDataReloaded(); 129 private onUpdateFavorStateFunc: Function = (item: MediaItem): void => this.onUpdateFavorState(item); 130 131 onPlaceholderChanged() { 132 Log.debug(TAG, 'onPlaceholderChanged placeholderIndex is ' + this.placeholderIndex); 133 if (this.placeholderIndex != -1) { 134 this.scroller.scrollToIndex(this.placeholderIndex); 135 } 136 } 137 138 initParams(): void { 139 this.isSelectedMode = false; 140 this.isShow = true; 141 } 142 143 onIndexChange(): void { 144 Log.info(TAG, `onIndexChange ${this.PhotoGridPageIndex}`) 145 if (this.PhotoGridPageIndex != Constants.INVALID) { 146 this.scroller.scrollToIndex(this.PhotoGridPageIndex); 147 } 148 } 149 150 doAnimation(): void { 151 animateTo({ 152 duration: BrowserConstants.PHONE_LINK_ALBUM_ACTIONBAR_DURATION, 153 delay: BrowserConstants.PHONE_LINK_ALBUM_ACTIONBAR_DELAY, 154 curve: Curve.Sharp 155 }, () => { 156 AppStorage.SetOrCreate<number>(Constants.KEY_OF_ALBUM_ACTIONBAR_OPACITY, 1); 157 }) 158 animateTo({ 159 duration: BrowserConstants.PHONE_LINK_OUT_PHOTO_GRID_ACTIONBAR_DURATION, 160 curve: Curve.Sharp 161 }, () => { 162 AppStorage.SetOrCreate<number>(Constants.KEY_OF_PHOTO_GRID_ACTIONBAR_OPACITY, 0); 163 AppStorage.SetOrCreate<number>(Constants.KEY_OF_PHOTO_GRID_VIEW_OPACITY, 0); 164 AppStorage.SetOrCreate<number>(Constants.KEY_OF_ALBUM_OPACITY, 1); 165 }) 166 animateTo({ 167 duration: BrowserConstants.PHONE_LINK_PHOTO_GRID_TO_ALBUM_DURATION, 168 curve: Curve.Friction 169 }, () => { 170 AppStorage.SetOrCreate<number>(Constants.KEY_OF_SELECTED_ALBUM_INDEX, -1); 171 AppStorage.SetOrCreate<boolean>(Constants.KEY_OF_IS_SHOW_PHOTO_GRID_VIEW, false); 172 AppStorage.SetOrCreate<string>(Constants.KEY_OF_SELECTED_ALBUM_URI, ''); 173 }) 174 animateTo({ 175 duration: BrowserConstants.PHONE_LINK_PHOTO_GRID_TO_ALBUM_SCALE_DURATION, 176 curve: Curve.Friction 177 }, () => { 178 AppStorage.SetOrCreate<number>(Constants.KEY_OF_ALBUM_OTHER_SCALE, 1); 179 }) 180 } 181 182 onMenuClicked(action: Action): void { 183 Log.info(TAG, `onMenuClicked, action: ${action.actionID}`); 184 let menuContext: MenuContext; 185 let menuOperation: MenuOperation; 186 if (action.actionID === Action.BACK.actionID) { 187 if (this.isFromFACard) { 188 router.replaceUrl({ 189 url: 'pages/index', 190 params: { 191 jumpSource: JumpSourceToMain.ALBUM, 192 } 193 }); 194 } else { 195 if (router.getState().name === Constants.USER_FILE_MANAGER_PHOTO_TRANSITION_ALBUM) { 196 router.back(); 197 } else { 198 this.doAnimation(); 199 } 200 } 201 } else if (action.actionID === Action.CANCEL.actionID) { 202 this.onModeChange(); 203 } else if (action.actionID === Action.MULTISELECT.actionID) { 204 this.isSelectedMode = true; 205 } else if (action.actionID === Action.SELECT_ALL.actionID) { 206 this.mSelectManager.selectAll(true); 207 } else if (action.actionID === Action.DESELECT_ALL.actionID) { 208 this.mSelectManager.deSelectAll(); 209 } else if (action.actionID === Action.DELETE.actionID) { 210 menuContext = new MenuContext(); 211 menuContext 212 .withSelectManager(this.mSelectManager) 213 .withOperationStartCallback((): void => this.onDeleteStart()) 214 .withOperationEndCallback((): void => this.onDeleteEnd()) 215 .withBroadCast(this.broadCast) 216 .withAlbumUri(this.albumInfo.uri) 217 .withFromSelectMode(this.isSelectedMode) 218 .withAlbumInfo(this.albumInfo) 219 menuOperation = MenuOperationFactory.getInstance() 220 .createMenuOperation(BatchDeleteMenuOperation, menuContext); 221 menuOperation.doAction(); 222 } else if (action.actionID === Action.SHARE.actionID) { 223 menuContext = new MenuContext(); 224 menuContext.withFromSelectMode(true).withSelectManager(this.mSelectManager); 225 menuOperation = MenuOperationFactory.getInstance() 226 .createMenuOperation(ShareMenuOperation, menuContext); 227 menuOperation.doAction(); 228 } else if (action.actionID === Action.INFO.actionID) { 229 this.hidePopup = true; 230 this.openDetailsDialog(); 231 } else if (action.actionID === Action.CLEAR_RECYCLE.actionID) { 232 menuContext = new MenuContext(); 233 menuContext 234 .withSelectManager(this.mSelectManager) 235 .withOperationStartCallback((): void => this.onDeleteStart()) 236 .withOperationEndCallback((): void => this.onDeleteEnd()) 237 .withBroadCast(this.broadCast) 238 .withAlbumUri(UserFileManagerAccess.getInstance() 239 .getSystemAlbumUri(UserFileManagerAccess.TRASH_ALBUM_SUB_TYPE)) 240 .withAlbumInfo(this.albumInfo) 241 menuOperation = MenuOperationFactory.getInstance() 242 .createMenuOperation(ClearRecycleMenuOperation, menuContext); 243 menuOperation.doAction(); 244 } else if (action.actionID === Action.RECOVER.actionID) { 245 menuContext = new MenuContext(); 246 menuContext 247 .withAlbumUri(UserFileManagerAccess.getInstance() 248 .getSystemAlbumUri(UserFileManagerAccess.TRASH_ALBUM_SUB_TYPE)) 249 .withSelectManager(this.mSelectManager) 250 .withOperationStartCallback((): void => this.onDeleteStart()) 251 .withOperationEndCallback((): void => this.onDeleteEnd()) 252 .withBroadCast(this.broadCast) 253 .withAlbumInfo(this.albumInfo) 254 menuOperation = MenuOperationFactory.getInstance() 255 .createMenuOperation(BatchRecoverMenuOperation, menuContext); 256 menuOperation.doAction(); 257 } else if (action.actionID === Action.MOVE.actionID) { 258 this.mSelectManager.getSelectedItems((selectedItems: Array<MediaItem>) => { 259 Log.info(TAG, `Get selected items success, size: ${selectedItems.length}, start route to select album page`); 260 this.routeToSelectAlbumPage(MediaOperationType.Move, selectedItems); 261 }) 262 } else if (action.actionID === Action.ADD.actionID) { 263 this.mSelectManager.getSelectedItems((selectedItems: Array<MediaItem>) => { 264 Log.info(TAG, `Get selected items success, size: ${selectedItems.length}, start route to select album page`); 265 this.routeToSelectAlbumPage(MediaOperationType.Add, selectedItems); 266 }) 267 } else if (action.actionID === Action.REMOVE_FROM.actionID) { 268 menuContext = new MenuContext(); 269 menuContext 270 .withSelectManager(this.mSelectManager) 271 .withOperationStartCallback((): void => this.onRemoveStart()) 272 .withOperationEndCallback((): void => this.onRemoveEnd()) 273 .withBroadCast(this.broadCast) 274 .withAlbumUri(this.albumInfo.uri) 275 .withFromSelectMode(this.isSelectedMode) 276 menuOperation = MenuOperationFactory.getInstance() 277 .createMenuOperation(BatchRemoveMenuOperation, menuContext); 278 menuOperation.doAction(); 279 } else if (action.actionID === Action.NEW.actionID) { 280 this.routeToAddMediaPage(); 281 } else if (action.actionID === Action.DOWNLOAD.actionID) { 282 menuContext = new MenuContext(); 283 menuContext 284 .withSelectManager(this.mSelectManager) 285 .withOperationStartCallback((): void => this.onDownloadStart()) 286 .withOperationEndCallback(async (err: Error, count: number, total: number): Promise<void> => this.onDownloadEnd(err as Object, count, total)) 287 .withBroadCast(this.broadCast) 288 menuOperation = MenuOperationFactory.getInstance().createMenuOperation(AddMenuOperation, menuContext); 289 menuOperation.doAction(); 290 } 291 } 292 293 async openDetailsDialog(): Promise<void> { 294 if (this.totalSelectedCount == 0) { 295 Log.error(TAG, 'no select error'); 296 return; 297 } else if (this.totalSelectedCount == 1) { 298 Log.info(TAG, 'totalSelectedCount is 1'); 299 await this.mSelectManager.getSelectedItems((selectItems: MediaItem[]) => { 300 if (selectItems.length != 1) { 301 Log.error(TAG, 'get selectItems is error'); 302 return; 303 } 304 this.broadCast.emit(BroadCastConstants.SHOW_DETAIL_DIALOG, [selectItems[0], this.isDistributedAlbum]); 305 }); 306 } else { 307 await this.mSelectManager.getSelectedItems((selectItems: MediaItem[]) => { 308 if (selectItems.length <= 1) { 309 Log.error(TAG, 'get selectItems is error'); 310 return; 311 } 312 let size = 0; 313 selectItems.forEach((item) => { 314 size = size + item.size; 315 }) 316 317 Log.info(TAG, `openDetailsDialog size: ${size}`); 318 this.broadCast.emit(BroadCastConstants.SHOW_MULTI_SELECT_DIALOG, [this.totalSelectedCount, size]); 319 }); 320 return; 321 } 322 } 323 324 routeToSelectAlbumPage(pageType: string, selectedItems: Array<MediaItem>): void { 325 this.routerStart = true; 326 router.pushUrl({ 327 url: 'pages/MediaOperationPage', 328 params: { 329 pageFrom: Constants.MEDIA_OPERATION_FROM_PHOTO_GRID, 330 pageType: pageType, 331 albumInfo: this.albumInfo, 332 selectedItems: selectedItems 333 } 334 }); 335 } 336 337 routeToAddMediaPage(): void { 338 router.pushUrl({ 339 url: 'pages/AlbumSelect', 340 params: { 341 albumName: this.albumInfo.albumName, 342 albumUri: this.albumInfo.uri 343 } 344 }); 345 } 346 347 onCopyStart(): void { 348 Log.info(TAG, `onCopyStart`); 349 this.isDataFreeze = true; 350 MediaObserver.getInstance().unregisterObserver(this.dataObserver); 351 this.dataSource.freeze(); 352 } 353 354 onCopyEnd(err: Object, count: number, total: number): void { 355 Log.info(TAG, `onCopyEnd count: ${count}, total: ${total}`); 356 this.isDataFreeze = false; 357 this.onModeChange(); 358 MediaObserver.getInstance().registerObserver(this.dataObserver); 359 this.dataSource.onChange('image'); 360 this.dataSource.unfreeze(); 361 if (err) { 362 UiUtil.showToast($r('app.string.copy_failed_single')); 363 } 364 } 365 366 onDownloadStart(): void { 367 Log.info(TAG, `onDownloadStart`); 368 this.isDataFreeze = true; 369 MediaObserver.getInstance().unregisterObserver(this.dataObserver); 370 this.dataSource.freeze(); 371 } 372 373 async onDownloadEnd(err: Object, count: number, total: number): Promise<void> { 374 Log.info(TAG, `onDownloadEnd count: ${count}, total: ${total}`); 375 this.isDataFreeze = false; 376 this.onModeChange(); 377 MediaObserver.getInstance().registerObserver(this.dataObserver); 378 this.dataSource.onChange('image'); 379 this.dataSource.unfreeze(); 380 if (err) { 381 if (total > 1) { 382 Log.error(TAG, `get selectItems is error ${count}`); 383 let str = await UiUtil.getResourceString($r('app.string.download_failed_multi')); 384 let message = str.replace('%d', count.toString()); 385 prompt.showToast({ 386 message: message, 387 duration: UiUtil.TOAST_DURATION, 388 bottom: '200vp' 389 }); 390 } else { 391 UiUtil.showToast($r('app.string.download_failed_single')) 392 } 393 } else { 394 UiUtil.showToast($r('app.string.download_progress_done')); 395 } 396 } 397 398 onMoveStart(): void { 399 Log.info(TAG, `onMoveStart`); 400 this.isDataFreeze = true; 401 MediaObserver.getInstance().unregisterObserver(this.dataObserver); 402 this.dataSource.freeze(); 403 } 404 405 onMoveEnd(err: Object, count: number, total: number): void { 406 Log.info(TAG, `onMoveEnd count: ${count}, total: ${total}`); 407 this.isDataFreeze = false; 408 this.onModeChange(); 409 MediaObserver.getInstance().registerObserver(this.dataObserver); 410 this.dataSource.switchRefreshOn(); 411 this.dataSource.onChange('image'); 412 this.dataSource.unfreeze(); 413 if (err) { 414 UiUtil.showToast($r('app.string.move_failed_single')); 415 } 416 } 417 418 onDeleteStart(): void { 419 Log.info(TAG, `onDeleteStart`); 420 this.deleteMode = true; 421 this.isDataFreeze = true; 422 this.onModeChange(); 423 MediaObserver.getInstance().unregisterObserver(this.dataObserver); 424 this.dataSource.freeze(); 425 MediaObserver.getInstance().freezeNotify(); 426 } 427 428 onDeleteEnd(): void { 429 Log.info(TAG, `onDeleteEnd`); 430 this.isDataFreeze = false; 431 MediaObserver.getInstance().unfreezeNotify(); 432 MediaObserver.getInstance().forceNotify(); 433 MediaObserver.getInstance().registerObserver(this.dataObserver); 434 this.dataSource.onChange('image'); 435 this.dataSource.unfreeze(); 436 } 437 438 onRemoveStart(): void { 439 Log.info(TAG, `onRemoveStart`); 440 this.deleteMode = true; 441 this.isDataFreeze = true; 442 MediaObserver.getInstance().unregisterObserver(this.dataObserver); 443 this.dataSource.freeze(); 444 } 445 446 onRemoveEnd(): void { 447 Log.info(TAG, `onRemoveEnd`); 448 this.isDataFreeze = false; 449 this.onModeChange(); 450 MediaObserver.getInstance().registerObserver(this.dataObserver); 451 this.dataSource.onChange('image'); 452 this.dataSource.unfreeze(); 453 } 454 455 onModeChange(): void { 456 Log.info(TAG, 'onModeChange'); 457 this.isSelectedMode = false; 458 this.isAllSelected = false; 459 this.mSelectManager.onModeChange(false); 460 AppStorage.delete(Constants.PHOTO_GRID_SELECT_MANAGER); 461 } 462 463 onPageChanged(): void { 464 this.params = router.getParams() as Params; 465 if (this.pageStatus) { 466 this.onPageShow(); 467 } else { 468 this.onPageHide(); 469 } 470 } 471 472 onPageShow(): void { 473 this.appBroadCast.emit(BroadCastConstants.THIRD_ROUTE_PAGE, []); 474 this.isShow = true; 475 if (this.routerStart && this.params != null && this.params.pageType != null) { 476 Log.info(TAG, 'MediaOperation back'); 477 if (this.params.pageType === MediaOperationType.Move) { 478 this.moveOperation(this.params.albumName, this.params.albumUri); 479 } else if (this.params.pageType === MediaOperationType.Add) { 480 this.addOperation(this.params.albumName, this.params.albumUri); 481 } 482 } 483 MediaObserver.getInstance().registerObserver(this.dataObserver); 484 this.isMvOrCpSeparatesItem = false; 485 this.mvOrCpSeparatesItem = new MediaItem(); 486 this.routerStart = false; 487 this.onActive(); 488 } 489 490 onPageHide(): void { 491 this.isShow = false; 492 this.onInActive(); 493 } 494 495 onActive(): void { 496 if (!this.isActive) { 497 Log.info(TAG, 'onActive'); 498 this.isActive = true; 499 this.dataSource && this.dataSource.onActive(); 500 if (this.isSelectedMode) { 501 this.totalSelectedCount = this.mSelectManager.getSelectedCount(); 502 this.dataSource.forceUpdate(); 503 } 504 } 505 } 506 507 onInActive(): void { 508 if (this.isActive) { 509 Log.info(TAG, 'onInActive'); 510 this.isActive = false; 511 } 512 } 513 514 updateRightClickMenuList(): void { 515 if (!this.isSelectedMode) { 516 this.onModeChange(); 517 } 518 this.rightClickMenuList = new Array<Action>(); 519 if (this.albumInfo) { 520 let isRecycleAlbum: boolean = this.albumInfo.isTrashAlbum; 521 if (isRecycleAlbum) { 522 this.rightClickMenuList = [Action.RECOVER, Action.DELETE, 523 this.isSelectedMode ? Action.MULTISELECT_INVALID : Action.MULTISELECT]; 524 } else { 525 if (!this.isSelectedMode) { 526 this.rightClickMenuList.push(Action.MULTISELECT) 527 } 528 this.rightClickMenuList.push(Action.DELETE); 529 if (!this.albumInfo.isSystemAlbum) { 530 this.rightClickMenuList.push(Action.MOVE); 531 this.rightClickMenuList.push(Action.REMOVE_FROM); 532 } 533 this.rightClickMenuList.push(Action.ADD, Action.INFO); 534 } 535 } 536 } 537 538 aboutToAppear(): void { 539 Log.debug(TAG, `aboutToAppear`); 540 TraceControllerUtils.startTrace('PhotoGridPageAboutToAppear'); 541 this.initParams(); 542 if (router.getState().name === Constants.USER_FILE_MANAGER_PHOTO_TRANSITION_ALBUM) { 543 this.photoGridActionBarOpacity = 1; 544 this.photoGridViewOpacity = 1; 545 } 546 let param: ParamAlbumInfo; 547 param = router.getParams() as ParamAlbumInfo; 548 if (!param || (param && !param.item)) { 549 param = AppStorage.get<ParamAlbumInfo>(Constants.KEY_OF_PHOTO_GRID_VIEW_ALBUM_ITEM) as ParamAlbumInfo; 550 } 551 if (param != null) { 552 if (param.isFromFACard) { 553 this.isFromFACard = param.isFromFACard; 554 } 555 this.albumInfo = JSON.parse(param.item); 556 this.title = this.albumInfo.albumName; 557 this.dataSource.setAlbumUri(this.albumInfo.uri); 558 if (this.albumInfo.mediaItem) { 559 let mediaItem = this.albumInfo.mediaItem; 560 this.dataSource.items = [mediaItem]; 561 this.dataSource.size = 1; 562 this.dataSource.dataIndexes = [0]; 563 this.photoTotalCount = this.albumInfo.count; 564 } 565 } 566 567 let self = this; 568 this.dataSource.setBroadCast(this.broadCast) 569 this.mSelectManager.setPhotoDataImpl(); 570 this.mSelectManager.setAlbumUri(this.albumInfo.uri); 571 MediaObserver.getInstance().registerObserver(this.dataObserver); 572 573 this.broadCast.on(BroadCastConstants.SELECT, this.selectFunc); 574 this.broadCast.on(BroadCastConstants.JUMP_PHOTO_BROWSER, this.jumpPhotoBrowserFunc); 575 this.broadCast.on(BroadCastConstants.JUMP_THIRD_PHOTO_BROWSER, this.jumpThirdPhotoBrowserFunc); 576 this.broadCast.on(Constants.ON_LOADING_FINISHED, this.onLoadingFinishedFunc); 577 this.appBroadCast.on(BroadCastConstants.UPDATE_DATA_SOURCE, this.onUpdateFavorStateFunc); 578 this.appBroadCast.on(BroadCastConstants.DO_ANIMATION, (): void => { 579 this.doAnimation(); 580 this.appBroadCast.off(BroadCastConstants.DO_ANIMATION, null); 581 }); 582 583 AppStorage.SetOrCreate(Constants.PHOTO_GRID_SELECT_MANAGER, this.mSelectManager); 584 this.mSelectManager.registerCallback('allSelect', (newState: boolean) => { 585 Log.info(TAG, `allSelect ${newState}`); 586 if (this.isDataFreeze) { 587 return; 588 } 589 this.isAllSelected = newState; 590 this.dataSource.forceUpdate(); 591 }); 592 this.mSelectManager.registerCallback('updateCount', (newState: number) => { 593 Log.info(TAG, `updateSelectedCount ${newState}`); 594 if (this.isDataFreeze) { 595 return; 596 } 597 this.moreMenuList = Boolean(newState) ? (this.albumInfo.isSystemAlbum ? [Action.ADD, Action.INFO] : [Action.MOVE, Action.ADD, Action.REMOVE_FROM, Action.INFO]) 598 : (this.albumInfo.isSystemAlbum ? [Action.ADD_INVALID, Action.INFO_INVALID] : [Action.MOVE_INVALID, Action.ADD_INVALID, Action.REMOVE_FROM_INVALID, Action.INFO_INVALID]); 599 this.totalSelectedCount = newState; 600 }); 601 this.mSelectManager.registerCallback('select', (newState: number) => { 602 Log.info(TAG, `select ${newState}`); 603 if (this.isDataFreeze) { 604 return; 605 } 606 this.dataSource.onDataChanged(newState); 607 }); 608 this.dataSource.registerCallback('updateCount', (newState: number) => { 609 Log.info(TAG, `updateTotalCount ${newState}`); 610 self.isShowScrollBar = (newState > Constants.PHOTOS_CNT_FOR_HIDE_SCROLL_BAR); 611 self.isEmpty = !Boolean(newState) 612 self.mSelectManager.setTotalCount(newState); 613 }); 614 615 this.broadCast.on(BroadCastConstants.ON_DATA_RELOADED, this.onDataReloadedFunc); 616 617 ScreenManager.getInstance().on(ScreenManager.ON_WIN_SIZE_CHANGED, this.onWindowSizeChangeCallBack); 618 619 this.initGridRowCount(); 620 this.moreMenuList = this.albumInfo.isSystemAlbum ? [Action.ADD, Action.INFO] : [Action.MOVE, Action.ADD, Action.REMOVE_FROM, Action.INFO]; 621 this.updateRightClickMenuList(); 622 TraceControllerUtils.finishTrace('PhotoGridPageAboutToAppear'); 623 } 624 625 private select(position: number, key: string, value: boolean, callback: Function): void { 626 if (this.mSelectManager.toggle(key, value, position)) { 627 Log.info(TAG, 'enter event process') 628 if (!this.isSelectedMode) { 629 this.isSelectedMode = true; 630 } 631 callback(); 632 } 633 } 634 635 private jumpPhotoBrowser(name: string, item: MediaItem, geometryTapIndex: number, geometryTransitionString: string): void { 636 let targetIndex = this.dataSource.getDataIndex(item); 637 if (targetIndex == Constants.NOT_FOUND) { 638 Log.error(TAG, 'targetIndex is not found'); 639 return; 640 } 641 Log.info(TAG, `jump to photo browser at index: ${targetIndex}`); 642 let pageEntryFrom = Constants.ENTRY_FROM.NORMAL; 643 if (this.albumInfo.isTrashAlbum) { 644 pageEntryFrom = Constants.ENTRY_FROM.RECYCLE; 645 } else if (this.isDistributedAlbum) { 646 pageEntryFrom = Constants.ENTRY_FROM.DISTRIBUTED; 647 } 648 649 AppStorage.SetOrCreate(Constants.APP_KEY_PHOTO_BROWSER, this.dataSource); 650 if (geometryTapIndex !== undefined && geometryTransitionString !== undefined) { 651 this.jumpToPhotoBrowserGeometryTransition( 652 targetIndex, name, pageEntryFrom, geometryTapIndex, geometryTransitionString); 653 } else { 654 this.jumpToPhotoBrowserNormal(targetIndex, name, pageEntryFrom); 655 } 656 } 657 658 private jumpThirdPhotoBrowser(name: string, item: MediaItem, geometryTapIndex: number, geometryTransitionString: string): void { 659 Log.info(TAG, 'JUMP_THIRD_PHOTO_BROWSER'); 660 let targetIndex = this.dataSource.getDataIndex(item); 661 if (targetIndex == Constants.NOT_FOUND) { 662 Log.error(TAG, 'targetIndex is not found'); 663 return; 664 } 665 Log.info(TAG, `jump to photo browser at index: ${targetIndex} ${name}`); 666 let pageEntryFrom = Constants.ENTRY_FROM.NORMAL; 667 if (this.albumInfo.isTrashAlbum) { 668 pageEntryFrom = Constants.ENTRY_FROM.RECYCLE; 669 } else if (this.isDistributedAlbum) { 670 pageEntryFrom = Constants.ENTRY_FROM.DISTRIBUTED; 671 } 672 AppStorage.SetOrCreate(Constants.PHOTO_GRID_SELECT_MANAGER, this.mSelectManager); 673 AppStorage.SetOrCreate(Constants.APP_KEY_PHOTO_BROWSER, this.dataSource); 674 if (geometryTapIndex !== undefined && geometryTransitionString !== undefined) { 675 this.jumpToSelectPhotoBrowserGeometryTransition( 676 targetIndex, name, pageEntryFrom, geometryTapIndex, geometryTransitionString); 677 } else { 678 this.jumpToSelectPhotoBrowserNormal(targetIndex, name, pageEntryFrom); 679 } 680 } 681 682 private onLoadingFinished(size: number): void { 683 Log.info(TAG, `ON_LOADING_FINISHED size: ${size}`); 684 } 685 686 private onDataReloaded(): void { 687 Log.info(TAG, 'ON_DATA_RELOADED'); 688 if (this.deleteMode) { 689 animateTo({ duration: 300 }, () => { 690 this.dataSource.onDataReloaded(); 691 }) 692 this.deleteMode = false; 693 } else { 694 this.dataSource.onDataReloaded(); 695 } 696 } 697 698 699 updateFirstPhotoItemInfo(item: MediaItem, isFirstPhotoItem: boolean): void { 700 if (item) { 701 AppStorage.SetOrCreate<boolean>(Constants.KEY_OF_IS_FIRST_PHOTO_ITEM, isFirstPhotoItem); 702 let albumUri = AppStorage.Get<string>(Constants.KEY_OF_ALBUM_URI); 703 let transitionId = `${item.hashCode}_${albumUri}`; 704 Log.info(TAG, `updateFirstPhotoItemInfo transitionId: ${transitionId}`); 705 AppStorage.Set<string>(Constants.KEY_OF_GEOMETRY_TRANSITION_ID_HEIGHT, transitionId); 706 } 707 } 708 709 jumpToPhotoBrowserNormal(targetIndex: number, name: string, pageEntryFrom: number) { 710 Log.debug(TAG, 'start jump to photo browser in normal'); 711 router.pushUrl({ 712 url: 'pages/PhotoBrowser', 713 params: { 714 position: targetIndex, 715 transition: name, 716 leftBlank: this.leftBlank, 717 pageFrom: pageEntryFrom, 718 deviceName: this.deviceName, 719 albumInfo: this.albumInfo 720 } 721 }); 722 } 723 724 jumpToPhotoBrowserGeometryTransition(targetIndex: number, name: string, pageEntryFrom: number, 725 geometryTapIndex: number, geometryTransitionString: string) { 726 Log.debug(TAG, 'start jump to photo browser in geometry transition'); 727 728 interface Params { 729 position: number; 730 transition: string; 731 leftBlank: number[]; 732 pageFrom: number; 733 deviceName: string; 734 albumInfo: AlbumInfo; 735 } 736 737 let params: Params = { 738 position: targetIndex, 739 transition: name, 740 leftBlank: this.leftBlank, 741 pageFrom: pageEntryFrom, 742 deviceName: this.deviceName, 743 albumInfo: this.albumInfo 744 } 745 this.browserController.showBrowser(geometryTapIndex, geometryTransitionString, TAG, params); 746 } 747 748 jumpToSelectPhotoBrowserNormal(targetIndex: number, name: string, pageEntryFrom: number) { 749 Log.debug(TAG, 'start jump to select photo browser in normal'); 750 router.pushUrl({ 751 url: 'pages/SelectPhotoBrowser', 752 params: { 753 position: targetIndex, 754 transition: name, 755 pageFrom: pageEntryFrom, 756 } 757 }); 758 } 759 760 jumpToSelectPhotoBrowserGeometryTransition(targetIndex: number, name: string, pageEntryFrom: number, 761 geometryTapIndex: number, geometryTransitionString: string) { 762 Log.debug(TAG, 'start jump to select photo browser in geometry transition'); 763 interface Params { 764 position: number; 765 transition: string; 766 pageFrom: number; 767 } 768 769 const params: Params = { 770 position: targetIndex, 771 transition: name, 772 pageFrom: pageEntryFrom, 773 }; 774 this.browserController.showSelectBrowser(geometryTapIndex, geometryTransitionString, TAG, params); 775 } 776 777 onMediaLibDataChange(changeType: string): void { 778 Log.info(TAG, `onMediaLibDataChange type: ${changeType}`); 779 this.dataSource.switchRefreshOn(); 780 this.dataSource.onChange(changeType); 781 } 782 783 aboutToDisappear(): void { 784 Log.info(TAG, `aboutToDisappear`); 785 ScreenManager.getInstance().off(ScreenManager.ON_WIN_SIZE_CHANGED, this.onWindowSizeChangeCallBack); 786 this.broadCast.off(BroadCastConstants.SELECT, this.selectFunc); 787 this.broadCast.off(BroadCastConstants.JUMP_PHOTO_BROWSER, this.jumpPhotoBrowserFunc); 788 this.broadCast.off(BroadCastConstants.JUMP_THIRD_PHOTO_BROWSER, this.jumpThirdPhotoBrowserFunc); 789 this.broadCast.off(Constants.ON_LOADING_FINISHED, this.onLoadingFinishedFunc); 790 this.broadCast.off(BroadCastConstants.ON_DATA_RELOADED, this.onDataReloadedFunc); 791 this.appBroadCast.off(BroadCastConstants.UPDATE_DATA_SOURCE, this.onUpdateFavorStateFunc); 792 this.dataSource.releaseBroadCast(); 793 MediaObserver.getInstance().unregisterObserver(this.dataObserver); 794 this.dataObserver.clearSource(); 795 } 796 797 isSameTransitionId(item: MediaItem): boolean { 798 return AppStorage.get<string>(Constants.KEY_OF_GEOMETRY_TRANSITION_ID_HEIGHT) as string === 799 `${item.hashCode}_${this.dataSource.albumUri}`; 800 } 801 802 getGeometryTransitionId(item: ViewData): string { 803 return TAG + (item.mediaItem as MediaItem).hashCode + this.mSelectManager.isItemSelected((item.mediaItem as MediaItem).uri); 804 } 805 806 build() { 807 Column() { 808 PhotoGridPageActionBar({ 809 title: this.title, 810 albumInfo: this.albumInfo, 811 isSystemAlbum: this.albumInfo.isSystemAlbum, 812 onMenuClicked: (action: Action): void => this.onMenuClicked(action), 813 isRecycle: this.albumInfo.isTrashAlbum, 814 isDistributedAlbum: this.isDistributedAlbum, 815 totalSelectedCount: $totalSelectedCount 816 }) 817 .opacity(this.photoGridActionBarOpacity) 818 819 if (this.isEmpty) { 820 NoPhotoComponent({ title: $r('app.string.no_distributed_photo_head_title_album') }) 821 } else { 822 if (this.albumInfo.isTrashAlbum) { 823 Text($r('app.string.recycle_prompt_message', Constants.RECYCLE_DAYS_MAX)) 824 .fontColor($r('sys.color.ohos_id_color_text_secondary')) 825 .fontSize($r('sys.float.ohos_id_text_size_body2')) 826 .fontWeight(FontWeight.Regular) 827 .width(Constants.PERCENT_100) 828 .padding(this.isHorizontal ? { 829 left: $r('sys.float.ohos_id_max_padding_start'), 830 top: $r('app.float.recycle_prompt_message_margin_tb'), 831 bottom: $r('app.float.recycle_prompt_message_margin_tb') 832 } : { 833 left: $r('sys.float.ohos_id_max_padding_start'), 834 right: $r('sys.float.ohos_id_max_padding_end'), 835 top: $r('app.float.recycle_prompt_message_margin_tb'), 836 bottom: $r('app.float.recycle_prompt_message_margin_tb') 837 } 838 ) 839 } 840 Stack() { 841 Grid(this.scroller) { 842 LazyForEach(this.dataSource, (item: ViewData, index?: number) => { 843 if (!!item) { 844 GridItem() { 845 ImageGridItemComponent({ 846 dataSource: this.dataSource, 847 item: item.mediaItem, 848 isSelected: this.isSelectedMode ? 849 this.mSelectManager.isItemSelected((item.mediaItem as MediaItem).uri) : false, 850 isRecycle: this.albumInfo.isTrashAlbum, 851 pageName: Constants.PHOTO_TRANSITION_ALBUM, 852 onMenuClicked: (action: Action): void => this.onMenuClicked(action), 853 onMenuClickedForSingleItem: (action: Action, currentPhoto: MediaItem): void => { 854 this.onMenuClickedForSingleItem(action, currentPhoto); 855 }, 856 geometryTransitionString: this.getGeometryTransitionId(item), 857 mPosition: index, 858 selectedCount: $totalSelectedCount 859 }) 860 } 861 .zIndex(this.isSameTransitionId(item.mediaItem as MediaItem) || index === this.placeholderIndex ? 1 : 0) 862 .width(this.gridItemWidth) 863 .aspectRatio(1) 864 .key('AlbumGridImage' + index) 865 } 866 }, (item: ViewData, index?: number) => { 867 if (item == null || item == undefined) { 868 return JSON.stringify(item); 869 } 870 // Update animation object 871 if (index === 0) { 872 if (this.scrollIndex === 0) { 873 this.updateFirstPhotoItemInfo(item.mediaItem as MediaItem, true); 874 } else { 875 this.updateFirstPhotoItemInfo((this.dataSource.getData(this.scrollIndex) as ViewData)?.mediaItem as MediaItem, false); 876 } 877 } 878 return this.getGeometryTransitionId(item) 879 }) 880 } 881 .zIndex(-1) 882 .clip(false) 883 .onScrollIndex((index: number) => { 884 this.scrollIndex = index; 885 this.updateFirstPhotoItemInfo((this.dataSource.getData(index) as ViewData)?.mediaItem as MediaItem, false); 886 }) 887 .edgeEffect(EdgeEffect.Spring) 888 .scrollBar(BarState.Off) 889 .columnsTemplate('1fr '.repeat(this.gridRowCount)) 890 .columnsGap(Constants.GRID_GUTTER) 891 .rowsGap(Constants.GRID_GUTTER) 892 .cachedCount(Constants.GRID_CACHE_ROW_COUNT) 893 .transition(TransitionEffect.scale({ 894 x: BrowserConstants.PHOTO_GRID_Scale, 895 y: BrowserConstants.PHOTO_GRID_Scale, 896 z: BrowserConstants.PHOTO_GRID_Scale 897 })) 898 899 if (this.isShowScrollBar) { 900 GridScrollBar({ scroller: this.scroller }); 901 } 902 903 if (this.albumInfo.isTrashAlbum) { 904 Column() { 905 Row() { 906 Button({ type: ButtonType.Capsule, stateEffect: true }) { 907 Text($r('app.string.action_clear_recycle')) 908 .fontWeight(FontWeight.Medium) 909 .fontSize($r('sys.float.ohos_id_text_size_button1')) 910 .fontColor($r('sys.color.ohos_id_color_text_primary_activated')) 911 .margin({ 912 left: $r('app.float.dialog_double_buttons_margin'), 913 right: $r('app.float.dialog_double_buttons_margin') 914 }) 915 } 916 .key('ClearRecycleButton') 917 .height($r('app.float.details_dialog_button_height')) 918 .borderRadius($r('sys.float.ohos_id_corner_radius_button')) 919 .backgroundColor($r('sys.color.ohos_id_color_button_normal')) 920 .onClick(() => { 921 this.onMenuClicked && this.onMenuClicked(Action.CLEAR_RECYCLE); 922 }) 923 } 924 .borderRadius($r('sys.float.ohos_id_corner_radius_button')) 925 .backgroundColor($r('sys.color.ohos_id_color_sub_background')) 926 } 927 .hitTestBehavior(HitTestMode.Transparent) 928 .width(`100%`) 929 .height('100%') 930 .alignItems(HorizontalAlign.Center) 931 .justifyContent(FlexAlign.End) 932 .padding({ bottom: $r('sys.float.ohos_id_default_padding_bottom_fixed') }) 933 .visibility(this.isSelectedMode ? Visibility.Hidden : Visibility.Visible) 934 } 935 } 936 .clip(true) 937 .zIndex(-1) 938 .layoutWeight(1) 939 .padding({ 940 bottom: ((this.isSelectedMode) && !this.isHorizontal) ? Constants.ActionBarHeight : 0 941 }) 942 } 943 CustomDialogView({ broadCast: $broadCast }); 944 945 if (this.isSelectedMode) { 946 PhotoGridPageToolBar({ 947 onMenuClicked: (action: Action): void => this.onMenuClicked(action), 948 isRecycleAlbum: (this.albumInfo.isTrashAlbum), 949 isDistributedAlbum: this.isDistributedAlbum, 950 totalSelectedCount: $totalSelectedCount 951 }); 952 } 953 } 954 .clip(true) 955 .opacity(this.photoGridViewOpacity) 956 .backgroundColor($r('app.color.default_background_color')) 957 .padding({ 958 top: this.leftBlank[1] 959 }) 960 } 961 962 private onUpdateFavorState(item: MediaItem): void { 963 Log.debug(TAG, 'onUpdateFavorState'); 964 let index = this.dataSource.getIndexByMediaItem(item); 965 if (index != -1) { 966 this.dataSource.onDataChanged(index); 967 } 968 } 969 970 private moveOperation(albumName: string, albumUri: string): void { 971 let menuContext = new MenuContext(); 972 if (this.isMvOrCpSeparatesItem) { 973 menuContext.withMediaItem(this.mvOrCpSeparatesItem); 974 this.onMoveStart && this.onMoveStart(); 975 } else { 976 menuContext.withSelectManager(this.mSelectManager).withOperationStartCallback((): void => this.onMoveStart()); 977 } 978 menuContext.withOperationEndCallback((err: Error, count: number, total: number): void => this.onMoveEnd(err as Object, count, total)) 979 .withBroadCast(this.broadCast) 980 .withTargetAlbumName(albumName) 981 .withAlbumUri(albumUri); 982 let menuOperation = MenuOperationFactory.getInstance().createMenuOperation(MoveMenuOperation, menuContext); 983 AppStorage.SetOrCreate(Constants.APP_KEY_NEW_ALBUM_SOURCE, this.albumInfo.uri); 984 menuOperation.doAction(); 985 } 986 987 private addOperation(albumName: string, albumUri: string): void { 988 let menuContext = new MenuContext(); 989 if (this.isMvOrCpSeparatesItem) { 990 menuContext.withMediaItem(this.mvOrCpSeparatesItem); 991 this.onCopyStart && this.onCopyStart(); 992 } else { 993 menuContext.withSelectManager(this.mSelectManager).withOperationStartCallback((): void => this.onCopyStart()); 994 } 995 menuContext.withOperationEndCallback((err: Error, count: number, total: number): void => this.onCopyEnd(err as Object, count, total)) 996 .withBroadCast(this.broadCast) 997 .withTargetAlbumName(albumName) 998 .withAlbumUri(albumUri); 999 let menuOperation = MenuOperationFactory.getInstance().createMenuOperation(AddMenuOperation, menuContext); 1000 menuOperation.doAction(); 1001 } 1002 1003 private onMenuClickedForSingleItem(action: Action, currentPhoto: MediaItem) { 1004 Log.info(TAG, `single menu click, action: ${action?.actionID}, currentUri: ${currentPhoto?.uri}`); 1005 if (currentPhoto == undefined) { 1006 return; 1007 } 1008 let menuOperation: MenuOperation; 1009 let menuContext: MenuContext; 1010 if (action.actionID === Action.RECOVER.actionID) { 1011 menuContext = new MenuContext(); 1012 menuContext.withMediaItem(currentPhoto).withBroadCast(this.broadCast); 1013 menuOperation = MenuOperationFactory.getInstance() 1014 .createMenuOperation(RecoverMenuOperation, menuContext); 1015 menuOperation.doAction(); 1016 } else if (action.actionID === Action.DELETE.actionID) { 1017 menuContext = new MenuContext(); 1018 if (this.dataSource.albumUri == UserFileManagerAccess.getInstance() 1019 .getSystemAlbumUri(UserFileManagerAccess.TRASH_ALBUM_SUB_TYPE)) { 1020 menuContext.withAlbumUri(UserFileManagerAccess.getInstance() 1021 .getSystemAlbumUri(UserFileManagerAccess.TRASH_ALBUM_SUB_TYPE)); 1022 } 1023 menuContext.withMediaItem(currentPhoto).withBroadCast(this.broadCast); 1024 menuOperation = MenuOperationFactory.getInstance() 1025 .createMenuOperation(DeleteMenuOperation, menuContext); 1026 menuOperation.doAction(); 1027 } else if (action.actionID === Action.MOVE.actionID) { 1028 this.isMvOrCpSeparatesItem = true; 1029 this.mvOrCpSeparatesItem = currentPhoto; 1030 this.routeToSelectAlbumPage(MediaOperationType.Move, [currentPhoto]); 1031 } else if (action.actionID === Action.ADD.actionID) { 1032 this.isMvOrCpSeparatesItem = true; 1033 this.mvOrCpSeparatesItem = currentPhoto; 1034 this.routeToSelectAlbumPage(MediaOperationType.Add, [currentPhoto]); 1035 } else if (action.actionID === Action.REMOVE_FROM.actionID) { 1036 menuContext = new MenuContext(); 1037 menuContext.withMediaItem(currentPhoto).withBroadCast(this.broadCast); 1038 menuOperation = MenuOperationFactory.getInstance() 1039 .createMenuOperation(RemoveMenuOperation, menuContext); 1040 menuOperation.doAction(); 1041 } else if (action.actionID === Action.INFO.actionID) { 1042 this.broadCast.emit(BroadCastConstants.SHOW_DETAIL_DIALOG, [currentPhoto, false]); 1043 } 1044 } 1045 1046 private initGridRowCount(): void { 1047 let contentWidth = ScreenManager.getInstance().getWinWidth(); 1048 let margin = 0; 1049 let maxThumbWidth = px2vp(Constants.GRID_IMAGE_SIZE) * Constants.GRID_MAX_SIZE_RATIO; 1050 // 原型机竖屏为4不变,横屏需计算: currentBreakpoint == 'lg' 表示横屏 1051 const currentBreakpoint: string = AppStorage.get<string>('currentBreakpoint') as string; 1052 this.gridRowCount = currentBreakpoint == Constants.BREAKPOINT_LG ? 1053 Math.max(Constants.GRID_MIN_COUNT, Math.ceil(((contentWidth - Constants.NUMBER_2 * margin) 1054 + Constants.GRID_GUTTER) / (maxThumbWidth + Constants.GRID_GUTTER))) : Constants.GRID_MIN_COUNT; 1055 this.gridItemWidth = (contentWidth - (this.gridRowCount - 1) * Constants.GRID_GUTTER - 1056 Constants.NUMBER_2 * margin) / this.gridRowCount; 1057 Log.info(TAG, `initGridRowCount contentWidth: ${contentWidth}`); 1058 } 1059 1060 private onUpdateRemoteDevice(res: string, deviceId: string): void { 1061 Log.info(TAG, `onUpdateRemoteDevice`); 1062 if (res == 'offline') { 1063 Log.debug(TAG, `device offline route to album main`); 1064 router.back({ 1065 url: 'pages/index', 1066 params: { 1067 jumpSource: JumpSourceToMain.ALBUM, 1068 } 1069 }); 1070 } else { 1071 Log.error(TAG, `res code is err ${res}`); 1072 return; 1073 } 1074 } 1075} 1076 1077interface Params { 1078 albumName: string; 1079 albumUri: string; 1080 pageType: string; 1081}; 1082 1083interface ParamAlbumInfo { 1084 item: string; 1085 isFromFACard: boolean; 1086};