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 bundle from '@ohos.bundle'; 18import CommonEvent from '@ohos.commonEvent'; 19import window from '@ohos.window'; 20import { BrowserConstants, MenuOperation, ViewData } from '@ohos/common'; 21import { 22 Action, 23 AddMenuOperation, 24 AlbumDefine, 25 AlbumInfo, 26 BigDataConstants, 27 BreakpointSystem, 28 BroadCast, 29 BroadCastConstants, 30 BroadCastManager, 31 CommonObserverCallback, 32 Constants, 33 DateUtil, 34 DeleteMenuOperation, 35 JumpSourceToMain, 36 Log, 37 MediaDataSource, 38 MediaItem, 39 MediaObserver, 40 MediaOperationType, 41 MenuContext, 42 MenuOperationFactory, 43 MoveMenuOperation, 44 BrowserConstants as PhotoConstants, 45 PhotoDataSource, 46 RemoveMenuOperation, 47 ReportToBigDataUtil, 48 ScreenManager, 49 ShareMenuOperation, 50 TraceControllerUtils, 51 UiUtil, 52 UriDataSource, 53 UserFileManagerAccess, 54 WindowUtil 55} from '@ohos/common'; 56import { 57 BrowserController, 58 CustomDialogView, 59 PhotoBrowserComponentBg, 60 PhotoBrowserHolder, 61 PhotoSwiper 62} from '@ohos/common/CommonComponents'; 63import { 64 AddNotesMenuOperation, 65 FavoriteMenuOperation, 66 GotoPhotosMenuOperation, 67 RecoverMenuOperation, 68 RenameMenuOperation, 69 RotateMenuOperation 70} from '@ohos/browser'; 71import { 72 PhotoBrowserActionBar, 73 PhotoBrowserToolBar 74} from '@ohos/browser/BrowserComponents'; 75import ability from '@ohos.ability.ability'; 76import common from '@ohos.app.ability.common'; 77 78const TAG: string = 'PhotoBrowserComponent'; 79 80interface ParamBrowser { 81 pageFrom: number; 82 albumInfo: AlbumInfo; 83 clickThumbnailTime: number; 84 albumUri: string; 85 index: number; 86 uri: string; 87 viewData: ViewData; 88 viewDataIndex: string; 89 viewDataAlbum: string; 90 transition: string; 91 position: number; 92 isShowMenuFromThirdView: boolean; 93 deviceName: string; 94 deviceId: string; 95}; 96 97interface Params { 98 pageType: string; 99 albumName: string; 100 albumUri: string; 101}; 102 103interface TitleName { 104 title: string; 105 displayName: string; 106} 107 108// page of large photo 109@Component 110export struct PhotoBrowserComponent { 111 @Provide backgroundColorResource: Resource = $r('app.color.default_background_color'); 112 @Provide('dateTitle') photoDate: string = ''; 113 @Provide('timeLocationTitle') timeAndLocation: string = ''; 114 @Provide menuList: Action[] = []; 115 @Provide toolMenuList: Action[] = []; 116 @Provide topMenuList: Action[] = []; 117 @Provide moreMenuList: Action[] = []; 118 @Provide broadCast: BroadCast = new BroadCast(); 119 @Provide isShowBar: boolean = true; 120 @Provide onlyChangeBgColor: boolean = false; 121 @Provide canSwipe: boolean = true; 122 @Provide pageFrom: number = Constants.ENTRY_FROM.NORMAL; 123 @State @Watch('updateMoreMenu') currentShow: boolean = true; 124 @StorageLink('isHorizontal') @Watch('updateIsHorizontal') isHorizontal: boolean = ScreenManager.getInstance() 125 .isHorizontal(); 126 @StorageLink('timelinePageIndex') timelinePageIndex: number = Constants.INVALID; 127 @StorageLink('photoGridPageIndex') photoGridPageIndex: number = Constants.INVALID; 128 @StorageLink('isSplitMode') isSplitMode: boolean = ScreenManager.getInstance().isSplitMode(); 129 @StorageLink('leftBlank') leftBlank: number[] = 130 [0, ScreenManager.getInstance().getStatusBarHeight(), 0, ScreenManager.getInstance().getNaviBarHeight()]; 131 @StorageLink('entryFromHap') entryFromHap: number = Constants.ENTRY_FROM_NONE; 132 mTransition: string = ''; 133 albumUri = ''; 134 // swiper currentIndex, there may not be onChanged callback during data refresh, so mediaItem cannot be saved 135 @Provide('transitionIndex') currentIndex: number = Constants.NUMBER_0; 136 controller?: SwiperController = new SwiperController(); 137 @Prop @Watch('onPageChanged') pageStatus: boolean = false; 138 @StorageLink('geometryOpacity') geometryOpacity: number = 1; 139 @State geometryTransitionId: string = ''; 140 @Link isRunningAnimation: boolean; 141 @ObjectLink browserController: BrowserController; 142 @Provide isDeleting: boolean = false; 143 @Provide hidePopup: boolean = false; 144 private isFirstLoad: boolean = true; 145 private bundleFlags = Constants.NUMBER_0; 146 // DataSource 147 private dataSource: PhotoDataSource = new PhotoDataSource(); 148 private dataObserver: CommonObserverCallback = new CommonObserverCallback(this); 149 // The global BroadCast of the application process. Event registration and destruction should be paired 150 private appBroadCast: BroadCast = BroadCastManager.getInstance().getBroadCast(); 151 private isFromCamera = false; 152 private isFromViewDataWithMediaUri = false; 153 private isFromViewDataWithThirdUri = false; 154 private isFromFACard = false; 155 private isPullDown = false; 156 // the source of jump to the index page 157 private jumpSourceToMain: number = JumpSourceToMain.None; 158 // time when clicks the thumbnail from the camera 159 private clickThumbnailTime = Constants.NUMBER_0; 160 // time to view the current picture 161 private checkedTransition: string = ''; 162 private viewTime = Constants.NUMBER_0; 163 // When clicking quickly, only run aboutToAppear for the first time 164 private hasAppeared: boolean = false; 165 private albumInfo?: AlbumInfo; 166 private deviceName = ''; 167 private backFromCopy = false; 168 private uriFromThirdPartyApp: string = ''; 169 private editNewUri: string = ''; 170 private favorCacheItemsMap = new Map<String, MediaItem>() 171 private breakpointSystem: BreakpointSystem = new BreakpointSystem(); 172 private theDeleteItem: MediaItem | null = null; 173 private geometryTransitionEnable: boolean = false; 174 private isShowMenuFromThirdView: boolean = true; 175 private isToEdit = false; 176 private photoBrowserBackFunc: Function = (): void => this.photoBrowserBack(); 177 private onToggleBarsFunc: Function = (backgroundColorResource?: Resource): void => 178 this.onToggleBars(backgroundColorResource); 179 private showBarsFunc: Function = (backgroundColorResource?: Resource): void => this.showBars(backgroundColorResource); 180 private hideBarsFunc: Function = (backgroundColorResource?: Resource): void => this.hideBars(backgroundColorResource); 181 private pullDownStartFunc: Function = (): void => this.pullDownStart(); 182 private pullDownEndFunc: Function = (): void => this.pullDownEnd(); 183 private onDataSizeChangedFunc: Function = (size: number): void => this.onDataSizeChanged(size); 184 private onDataContentChangedFunc: Function = (): void => this.onDataContentChanged(); 185 private setFavorFunc: Function = (isFavor: boolean): void => this.setFavor(isFavor); 186 private doRenameFunc: Function = (result: TitleName): void => this.doRename(result); 187 private doRotateFunc: Function = (result: number): void => this.doRotate(result); 188 private pullDownStartWithEventFunc: Function = (event: KeyEvent): void => this.pullDownStartWithEvent(event); 189 private pullDownCancelFunc: Function = (): void => this.pullDownCancel(); 190 private onPhotoBrowserDeleteConfirmFunc: Function = (): void => this.onPhotoBrowserDeleteConfirm(); 191 private onPhotoBrowserRemoveConfirmFunc: Function = (): void => this.onPhotoBrowserRemoveConfirm(); 192 private doDeleteFunc: Function = (): void => this.doDelete(); 193 private onPhotoShowStateChangedFunc: Function = (state: boolean): void => this.onPhotoShowStateChanged(state); 194 private setSwiperDisableFunc: Function = (value: boolean): void => this.setSwiperDisable(value); 195 private onDataReloadWithEditFunc: Function = (): void => this.onDataReloadWithEdit(); 196 197 198 onPageChanged() { 199 Log.info(TAG, `call page status changed ${this.pageStatus}`) 200 if (this.pageStatus) { 201 this.onPageShow(); 202 } else { 203 this.onPageHide(); 204 } 205 } 206 207 discardCallback(): void { 208 Log.debug(TAG, 'discardCallback called'); 209 } 210 211 updateIsHorizontal(): void { 212 if (this.isHorizontal) { 213 ScreenManager.getInstance().setSystemUi(false); 214 } else { 215 if (this.isShowBar) { 216 ScreenManager.getInstance().setSystemUi(true); 217 } 218 } 219 220 if (!this.isFirstLoad) { 221 this.updateMenu(this.currentIndex); 222 } else { 223 this.isFirstLoad = false; 224 } 225 } 226 227 onMenuClicked(action: Action): void { 228 let actionID: number = action.actionID; 229 Log.info(TAG, `onMenuClicked, actionID: ${actionID}`); 230 let menuOperation: MenuOperation | null = null; 231 let menuContext: MenuContext = new MenuContext(); 232 let currentPhoto = this.getCurrentPhoto(); 233 if (actionID === Action.BACK.actionID) { 234 this.onBackPress(); 235 } else if (actionID === Action.INFO.actionID) { 236 if (currentPhoto == undefined) { 237 Log.warn(TAG, 'currentPhoto is undefined'); 238 return; 239 } 240 this.broadCast.emit(BroadCastConstants.SHOW_DETAIL_DIALOG, 241 [currentPhoto, this.pageFrom == Constants.ENTRY_FROM.DISTRIBUTED]); 242 } else if (actionID === Action.SHARE.actionID) { 243 if (currentPhoto == undefined) { 244 Log.warn(TAG, 'currentPhoto is undefined'); 245 return; 246 } 247 menuContext.withFromSelectMode(false).withMediaItem(currentPhoto); 248 menuOperation = MenuOperationFactory.getInstance() 249 .createMenuOperation(ShareMenuOperation, menuContext); 250 } else if (actionID === Action.NOT_FAVORITE.actionID || actionID === Action.FAVORITE.actionID) { 251 if (currentPhoto == undefined) { 252 Log.warn(TAG, 'currentPhoto is undefined.'); 253 return; 254 } 255 currentPhoto.isFavor = !currentPhoto.isFavor; 256 257 if (this.albumUri !== UserFileManagerAccess.getInstance() 258 .getSystemAlbumUri(UserFileManagerAccess.FAVORITE_ALBUM_SUB_TYPE)) { 259 let currentPhoto = this.getCurrentPhoto(); 260 menuContext.withMediaItem(currentPhoto).withBroadCast(this.broadCast); 261 menuOperation = MenuOperationFactory.getInstance().createMenuOperation(FavoriteMenuOperation, menuContext); 262 this.appBroadCast.emit(BroadCastConstants.UPDATE_DATA_SOURCE, [currentPhoto]); 263 } else { 264 if (currentPhoto.isFavor === true) { 265 if (this.favorCacheItemsMap.has(currentPhoto.uri)) { 266 this.favorCacheItemsMap.delete(currentPhoto.uri); 267 } else { 268 Log.error(TAG, `not fount item uri ${currentPhoto.uri}`); 269 } 270 } else { 271 this.favorCacheItemsMap.set(currentPhoto.uri, currentPhoto); 272 } 273 } 274 this.updateMenu(this.currentIndex); 275 this.geometryTransitionId = this.browserController.pageFrom + currentPhoto.getHashCode() + 'false'; 276 AppStorage.setOrCreate<string>('geometryTransitionBrowserId', this.geometryTransitionId); 277 } else if (actionID === Action.DELETE.actionID) { 278 if (currentPhoto == undefined) { 279 Log.warn(TAG, 'currentPhoto is undefined.'); 280 return; 281 } 282 menuContext.withAlbumInfo(this.albumInfo); 283 this.theDeleteItem = currentPhoto; 284 menuContext.withMediaItem(currentPhoto).withBroadCast(this.broadCast); 285 menuOperation = MenuOperationFactory.getInstance() 286 .createMenuOperation(DeleteMenuOperation, menuContext); 287 } else if (actionID === Action.RECOVER.actionID) { 288 if (currentPhoto == undefined) { 289 Log.warn(TAG, 'currentPhoto is undefined.'); 290 return; 291 } 292 menuContext.withMediaItem(currentPhoto).withBroadCast(this.broadCast); 293 menuOperation = MenuOperationFactory.getInstance() 294 .createMenuOperation(RecoverMenuOperation, menuContext); 295 } else if (actionID === Action.GOTO_PHOTOS.actionID) { 296 if (currentPhoto == undefined) { 297 Log.warn(TAG, 'currentPhoto is undefined.'); 298 return; 299 } 300 menuContext.withJumpSourceToMain(this.jumpSourceToMain); 301 menuOperation = MenuOperationFactory.getInstance() 302 .createMenuOperation(GotoPhotosMenuOperation, menuContext); 303 } else if (actionID === Action.EDIT.actionID) { 304 if (currentPhoto == undefined || currentPhoto.size == 0) { 305 Log.warn(TAG, 'currentPhoto is undefined or size is 0.'); 306 return; 307 } 308 AppStorage.setOrCreate<MediaItem | undefined>('EditorMediaItem', currentPhoto); 309 AppStorage.setOrCreate<string>('EditorAlbumUri', this.albumUri); 310 router.pushUrl({ 311 url: 'pages/EditMain' 312 }) 313 this.isToEdit = true; 314 } else if (actionID === Action.EDIT_INVALID.actionID) { 315 if (currentPhoto == undefined || currentPhoto.size == 0) { 316 Log.warn(TAG, 'currentPhoto is undefined or size is 0.'); 317 return; 318 } 319 } else if (actionID === Action.RENAME.actionID) { 320 this.hidePopup = true; 321 if (currentPhoto == undefined) { 322 Log.warn(TAG, 'currentPhoto is undefined.'); 323 return; 324 } 325 menuContext.withMediaItem(currentPhoto).withBroadCast(this.broadCast).withAlbumUri(this.albumUri); 326 menuOperation = MenuOperationFactory.getInstance().createMenuOperation(RenameMenuOperation, menuContext); 327 } else if (actionID === Action.ROTATE.actionID) { 328 if (currentPhoto == undefined) { 329 Log.warn(TAG, 'currentPhoto is undefined when onMenuClicked Action.RENAME.'); 330 return; 331 } 332 let rotateValue = currentPhoto.orientation - Constants.DEFAULT_ROTATE_VALUE + Constants.ROTATE_AROUND; 333 if (rotateValue >= Constants.ROTATE_AROUND) { 334 rotateValue = rotateValue - Constants.ROTATE_AROUND; 335 } 336 currentPhoto.orientation = rotateValue; 337 menuContext.withMediaItem(currentPhoto).withBroadCast(this.broadCast); 338 menuOperation = MenuOperationFactory.getInstance().createMenuOperation(RotateMenuOperation, menuContext); 339 } else if (actionID === Action.ADD_NOTES.actionID) { 340 if (currentPhoto == undefined) { 341 Log.warn(TAG, 'currentPhoto is undefined when onMenuClicked Action.RENAME.'); 342 return; 343 } 344 menuContext.withMediaItem(currentPhoto).withBroadCast(this.broadCast); 345 menuOperation = MenuOperationFactory.getInstance().createMenuOperation(AddNotesMenuOperation, menuContext); 346 } else if (actionID === Action.MOVE.actionID) { 347 if (currentPhoto == undefined) { 348 Log.warn(TAG, 'currentPhoto is undefined when onMenuClicked Action.MOVE.'); 349 return; 350 } 351 this.backFromCopy = true; 352 currentPhoto && currentPhoto.mediaType && 353 this.routeToSelectAlbumPage(MediaOperationType.Move, currentPhoto.mediaType); 354 return; 355 } else if (actionID === Action.ADD.actionID) { 356 if (currentPhoto == undefined) { 357 Log.warn(TAG, 'currentPhoto is undefined when onMenuClicked Action.ADD.'); 358 return; 359 } 360 this.backFromCopy = true; 361 currentPhoto && currentPhoto.mediaType && 362 this.routeToSelectAlbumPage(MediaOperationType.Add, currentPhoto.mediaType); 363 } else if (actionID === Action.REMOVE_FROM.actionID) { 364 if (currentPhoto == undefined) { 365 Log.warn(TAG, 'currentPhoto is undefined.'); 366 return; 367 } 368 369 menuContext.withAlbumUri(this.albumUri); 370 menuContext.withMediaItem(currentPhoto).withBroadCast(this.broadCast); 371 menuOperation = MenuOperationFactory.getInstance() 372 .createMenuOperation(RemoveMenuOperation, menuContext); 373 } else if (actionID === Action.DOWNLOAD.actionID) { 374 this.downLoad(); 375 } 376 if (!!menuOperation) { 377 menuOperation.doAction(); 378 } 379 } 380 381 routeToSelectAlbumPage(pageType: string, mediaType: number): void { 382 router.pushUrl({ 383 url: 'pages/MediaOperationPage', 384 params: { 385 pageFrom: Constants.MEDIA_OPERATION_FROM_PHOTO_BROWSER, 386 pageType: pageType, 387 albumInfo: this.albumInfo, 388 mediaType: mediaType 389 } 390 }); 391 } 392 393 onPhotoChanged(index: number): void { 394 Log.info(TAG, `onPhotoChanged start, index=${index}`); 395 this.reportToBigDataForPhotoSlide(index); 396 this.currentIndex = index; 397 this.updateActionBar(index); 398 let currentPhoto: MediaItem | undefined = this.getPhotoByIndex(index); 399 if (currentPhoto == undefined) { 400 Log.error(TAG, 'onPhotoChanged, item is undefined'); 401 } else { 402 let timelineIndex = this.dataSource.getPositionByIndex(index); 403 AppStorage.setOrCreate<number>('placeholderIndex', timelineIndex); 404 this.geometryTransitionId = this.browserController.pageFrom + currentPhoto.getHashCode() + 'false'; 405 AppStorage.setOrCreate<string>('geometryTransitionBrowserId', this.geometryTransitionId); 406 Log.debug(TAG, `onPhotoChanged, index: ${index}, currentPhoto: ${currentPhoto.uri}, \ 407 placeholderIndex ${AppStorage.get<number>('placeholderIndex') as number},\ 408 geometryTransitionBrowserId ${this.geometryTransitionId}, this.mTransition ${this.mTransition}, \ 409 pageFrom = ${this.pageFrom}`); 410 } 411 this.updatePixMapDataSource(); 412 } 413 414 onDataSizeChanged(size: number): void { 415 Log.info(TAG, `onDataSizeChanged, size is ${size}`); 416 if (size == 0 && !this.isToEdit) { 417 if (this.uriFromThirdPartyApp) { 418 return; 419 } 420 this.onBackPress(); 421 } 422 } 423 424 resetAlbum(albumUri: string): void { 425 this.currentIndex = 0; 426 Log.info(TAG, `not found in album[${this.albumUri}], so use ${albumUri} instead`); 427 this.albumUri = albumUri; 428 this.dataSource.resetAlbumUri(this.albumUri); 429 return; 430 } 431 432 updatePixMapDataSource(): void { 433 this.dataSource.updatePixMapDataSource(this.currentIndex); 434 } 435 436 updateActionBar(index: number): void { 437 let currentPhoto: MediaItem | undefined = this.getPhotoByIndex(index); 438 if (currentPhoto == undefined || this.isFromViewDataWithThirdUri) { 439 return; 440 } 441 this.photoDate = DateUtil.getLocalizedDate(currentPhoto?.getDataTaken()); 442 if (this.pageFrom == Constants.ENTRY_FROM.DISTRIBUTED) { 443 this.timeAndLocation = `${this.deviceName}/${DateUtil.getLocalizedTime(currentPhoto?.getDataTaken())}`; 444 } else { 445 this.timeAndLocation = DateUtil.getLocalizedTime(currentPhoto?.getDataTaken()); 446 } 447 this.updateMenu(index); 448 } 449 450 updateMenu(index: number): void { 451 let currentPhoto: MediaItem | undefined = this.getPhotoByIndex(index); 452 if (!currentPhoto) { 453 return; 454 } 455 456 if (this.albumUri == UserFileManagerAccess.getInstance() 457 .getSystemAlbumUri(UserFileManagerAccess.FAVORITE_ALBUM_SUB_TYPE)) { 458 let key = currentPhoto.uri; 459 if (this.favorCacheItemsMap.has(key)) { 460 let tempPhotoItem: MediaItem = this.favorCacheItemsMap.get(key) as MediaItem; 461 currentPhoto.isFavor = tempPhotoItem.isFavor; 462 this.favorCacheItemsMap.set(key, currentPhoto); 463 } 464 } 465 466 let pageFrom: number = this.pageFrom; 467 if (this.albumUri === UserFileManagerAccess.getInstance() 468 .getSystemAlbumUri(UserFileManagerAccess.TRASH_ALBUM_SUB_TYPE)) { 469 pageFrom = Constants.ENTRY_FROM.RECYCLE; 470 } 471 472 Log.info(TAG, `updateMenu album[${this.albumUri}]`); 473 474 let menuTemp: Action[] = []; 475 if (this.pageFrom == Constants.ENTRY_FROM.CAMERA || 476 this.pageFrom == Constants.ENTRY_FROM.CARD || 477 (this.isFromViewDataWithMediaUri == true && 478 this.albumUri != UserFileManagerAccess.getInstance() 479 .getSystemAlbumUri(UserFileManagerAccess.TRASH_ALBUM_SUB_TYPE))) { 480 menuTemp = [Action.GOTO_PHOTOS, Action.INFO]; 481 } else if (pageFrom == Constants.ENTRY_FROM.RECYCLE || this.isFromViewDataWithThirdUri == true) { 482 menuTemp = []; 483 } else { 484 menuTemp = [Action.INFO]; 485 } 486 if (!UiUtil.isActionArrayEqual(this.menuList, menuTemp)) { 487 this.menuList = menuTemp; 488 } 489 490 let list: Action[] = []; 491 if (pageFrom === Constants.ENTRY_FROM.NORMAL || pageFrom === Constants.ENTRY_FROM.CAMERA) { 492 list.push(currentPhoto.isFavor ? Action.FAVORITE : Action.NOT_FAVORITE, 493 ((currentPhoto.mediaType == UserFileManagerAccess.MEDIA_TYPE_IMAGE)) 494 ? Action.EDIT : Action.EDIT_INVALID, Action.DELETE, Action.MORE); // TODO: delete edit 495 } else if (pageFrom === Constants.ENTRY_FROM.RECYCLE) { 496 list.push(Action.RECOVER, Action.DELETE); 497 } else if (pageFrom === Constants.ENTRY_FROM.DISTRIBUTED) { 498 list.push(Action.DOWNLOAD); 499 } else { 500 list.push(currentPhoto.isFavor ? Action.FAVORITE : Action.NOT_FAVORITE, 501 ((currentPhoto.mediaType == UserFileManagerAccess.MEDIA_TYPE_IMAGE)) 502 ? Action.EDIT : Action.EDIT_INVALID, Action.DELETE, Action.MORE); // TODO: delete edit 503 } 504 505 if (this.isHorizontal) { 506 if (this.isShowMenuFromThirdView) { 507 this.menuList = this.menuList.concat(list); 508 } 509 this.toolMenuList = []; 510 } else { 511 if (this.isShowMenuFromThirdView) { 512 if (!UiUtil.isActionArrayEqual(this.toolMenuList, list)) { 513 this.toolMenuList = list; 514 } 515 } else { 516 this.toolMenuList = []; 517 } 518 } 519 let menuTempList: Action[] = []; 520 if (!this.albumInfo) { 521 // 照片页 522 menuTempList = [Action.ADD, Action.RENAME]; 523 } else { 524 // 指定相册 525 menuTempList = this.albumInfo.isSystemAlbum ? 526 [Action.ADD, Action.RENAME] : [Action.MOVE, Action.ADD, Action.REMOVE_FROM, Action.RENAME]; 527 } 528 if (!UiUtil.isActionArrayEqual(this.moreMenuList, menuTempList)) { 529 this.moreMenuList = menuTempList; 530 } 531 } 532 533 isShowMenuBigData(isShowMenuFromThirdView: boolean): void { 534 interface ShowMenuMsg { 535 isShowMenuFromThirdView: string 536 } 537 let isShowMenuMsg: ShowMenuMsg; 538 if (isShowMenuFromThirdView) { 539 this.isShowMenuFromThirdView = true; 540 isShowMenuMsg = { 541 isShowMenuFromThirdView: BigDataConstants.SHOW_MENU 542 } 543 } else if (isShowMenuFromThirdView == false) { 544 this.isShowMenuFromThirdView = false; 545 isShowMenuMsg = { 546 isShowMenuFromThirdView: BigDataConstants.HIDE_MENU 547 } 548 } else { 549 this.isShowMenuFromThirdView = true; 550 isShowMenuMsg = { 551 isShowMenuFromThirdView: BigDataConstants.UNDEFINED_IS_SHOW_MENU 552 } 553 } 554 this.updateMenu(this.currentIndex); 555 ReportToBigDataUtil.statisticReport(BigDataConstants.IS_SHOW_MENU_ID, isShowMenuMsg); 556 } 557 558 updateMoreMenu(): void { 559 this.moreMenuList = this.albumInfo?.isSystemAlbum ? 560 [Action.ADD, Action.RENAME] : [Action.MOVE, Action.ADD, Action.REMOVE_FROM, Action.RENAME]; 561 } 562 563 getCurrentPhoto(): MediaItem { 564 return this.dataSource?.getRawData(this.currentIndex).data; 565 } 566 567 getPhotoByIndex(index: number): MediaItem { 568 return this.dataSource?.getRawData(index).data; 569 } 570 571 async onMoveEnd(err: Object, count: number, total: number): Promise<void> { 572 Log.debug(TAG, `onMoveEnd count: ${count}, total: ${total}`); 573 if (err) { 574 UiUtil.showToast($r('app.string.move_failed_single')); 575 return; 576 } 577 let currentPhoto = this.getCurrentPhoto(); 578 let newItem = await this.dataSource.getDataByUri(currentPhoto.uri) 579 this.appBroadCast.emit(BroadCastConstants.UPDATE_DATA_SOURCE, [currentPhoto]); 580 } 581 582 onCopyEnd(err: Object, count: number, total: number): void { 583 Log.debug(TAG, `onCopyEnd count: ${count}, total: ${total}`); 584 if (err) { 585 UiUtil.showToast($r('app.string.copy_failed_single')); 586 } 587 } 588 589 async onDownloadEnd(err: Object, count: number, total: number): Promise<void> { 590 Log.debug(TAG, `onDownloadEnd count: ${count}, total: ${total}`); 591 this.appBroadCast.emit(BroadCastConstants.PHOTO_BROWSER_ACTIVE, [true, this.checkedTransition]); 592 if (err) { 593 UiUtil.showToast($r('app.string.download_failed_single')); 594 } else { 595 UiUtil.showToast($r('app.string.download_progress_done')); 596 } 597 } 598 599 onBackPress(): boolean { 600 Log.info(TAG, 'onBackPress'); 601 this.appBroadCast.emit('hideBar', []); 602 let currentPhoto = this.getPhotoByIndex(this.currentIndex); 603 this.broadCast.emit(BrowserConstants.RESET_DEFAULT_SCALE + currentPhoto?.uri, []); 604 this.controller?.finishAnimation((): void => this.onBackPressInner()); 605 return true; 606 } 607 608 onBackPressInner(): void { 609 Log.info(TAG, `onBackPressInner ${this.checkedTransition}`); 610 this.dataSource.release(); 611 if (this.checkedTransition === Constants.PHOTO_TRANSITION_TIMELINE) { 612 Log.info(TAG, 'onBackPress TimelinePage'); 613 this.timelinePageIndex = this.currentIndex; // call scrollTo 614 this.timelinePageIndex = Constants.INVALID; 615 } else if (this.checkedTransition === Constants.PHOTO_TRANSITION_ALBUM) { 616 Log.info(TAG, 'onBackPress PhotoGridPage'); 617 this.photoGridPageIndex = this.currentIndex; // call scrollTo 618 this.photoGridPageIndex = Constants.INVALID; 619 620 if (this.isFromFACard) { 621 if (this.isPullDown) { 622 this.isPullDown = false; 623 let context: common.UIAbilityContext = AppStorage.get<common.UIAbilityContext>('photosAbilityContext') as common.UIAbilityContext; 624 context.terminateSelf(); 625 } else { 626 let displayName: string = AppStorage.get<string>('form_displayName') as string; 627 let uri: string = AppStorage.get<string>('form_albumUri') as string; 628 let item: AlbumInfo = new AlbumInfo(undefined); 629 item.uri = uri; 630 item.albumName = displayName; 631 router.replaceUrl({ 632 url: 'pages/PhotoGridPage', 633 params: { 634 item: JSON.stringify(item), 635 isFromFACard: this.isFromFACard 636 } 637 }); 638 } 639 640 if (this.geometryTransitionEnable) { 641 UiUtil.resetGeometryTransitionParams(); 642 } 643 this.breakpointSystem.unregisterOrientationChange(); 644 WindowUtil.setPreferredOrientation(AppStorage.get<common.UIAbilityContext>('photosAbilityContext') as common.UIAbilityContext, 645 window.Orientation.UNSPECIFIED); 646 return; 647 } 648 } else if (this.checkedTransition === Constants.PHOTO_TRANSITION_CAMERA) { 649 Log.info(TAG, 'onBackPress Camera'); 650 // Entering from the camera does not need to return to close directly 651 let context: common.UIAbilityContext = AppStorage.get<common.UIAbilityContext>('photosAbilityContext') as common.UIAbilityContext; 652 context.terminateSelf(); 653 } else if (this.checkedTransition === Constants.PHOTO_TRANSITION_THIRD_APP) { 654 Log.info(TAG, 'onBackPress third app'); 655 this.setViewDataResult(true); 656 } 657 if (this.geometryTransitionEnable) { 658 this.browserController.hideBrowser(); 659 } else { 660 router.back({ 661 url: '', 662 params: { 663 index: this.currentIndex 664 } 665 }); 666 } 667 } 668 669 updatePhotoName(result: TitleName): void { 670 let currentPhoto = this.getCurrentPhoto(); 671 currentPhoto?.setTitle(result.title); 672 currentPhoto.displayName = result.displayName; 673 this.appBroadCast.emit(BroadCastConstants.UPDATE_DATA_SOURCE, [currentPhoto]); 674 } 675 676 aboutToDisappear(): void { 677 Log.info(TAG, 'photoBrowser aboutToDisappear'); 678 this.favorCacheItemsMap.forEach((item) => { 679 let menuFavorContext = new MenuContext().withMediaItem(item).withBroadCast(this.broadCast); 680 let menuFavorOperation = MenuOperationFactory.getInstance() 681 .createMenuOperation(FavoriteMenuOperation, menuFavorContext); 682 menuFavorOperation.doAction(); 683 }); 684 685 if (!this.isShowBar && !this.isHorizontal) { 686 ScreenManager.getInstance().setSystemUi(true); 687 } 688 // Click the thumbnail quickly, hasAppeared is false if it is not the first click. Return directly 689 if (!this.hasAppeared) { 690 return; 691 } 692 MediaObserver.getInstance().unregisterObserver(this.dataObserver); 693 this.dataObserver.clearSource(); 694 695 if (!this.isFromFACard) { 696 this.breakpointSystem.unregisterOrientationChange(); 697 WindowUtil.setPreferredOrientation(AppStorage.get<common.UIAbilityContext>('photosAbilityContext') as common.UIAbilityContext, 698 window.Orientation.UNSPECIFIED); 699 } 700 701 this.broadCast.off(PhotoConstants.TOGGLE_BAR, this.onToggleBarsFunc); 702 this.broadCast.off(PhotoConstants.HIDE_BARS, this.hideBarsFunc); 703 this.broadCast.off(PhotoConstants.SHOW_BARS, this.showBarsFunc); 704 this.broadCast.off(PhotoConstants.PULL_DOWN_START, this.pullDownStartFunc); 705 this.broadCast.off(PhotoConstants.PULL_DOWN_END, this.pullDownEndFunc); 706 this.broadCast.off(PhotoConstants.DATA_SIZE_CHANGED, this.onDataSizeChangedFunc); 707 this.broadCast.off(PhotoConstants.DATA_CONTENT_CHANGED, this.onDataContentChangedFunc); 708 this.broadCast.off(PhotoConstants.SET_FAVOR, this.setFavorFunc); 709 this.broadCast.off(PhotoConstants.RENAME, this.doRenameFunc); 710 this.broadCast.off(PhotoConstants.ROTATE, this.doRotateFunc); 711 this.broadCast.off(PhotoConstants.PULL_DOWN_START, this.pullDownStartWithEventFunc); 712 this.broadCast.off(PhotoConstants.PULL_DOWN_CANCEL, this.pullDownCancelFunc); 713 this.broadCast.off(PhotoConstants.PHOTO_BROWSER_DELETE_CONFIRM, this.onPhotoBrowserDeleteConfirmFunc); 714 this.broadCast.off(PhotoConstants.PHOTO_BROWSER_REMOVE_CONFIRM, this.onPhotoBrowserRemoveConfirmFunc); 715 this.broadCast.off(PhotoConstants.DELETE, this.doDeleteFunc); 716 this.broadCast.off(PhotoConstants.PHOTO_SHOW_STATE, this.onPhotoShowStateChangedFunc); 717 this.broadCast.off(PhotoConstants.SET_DISABLE_SWIPE, this.setSwiperDisableFunc); 718 this.broadCast.off(BroadCastConstants.ON_DATA_RELOADED_WITH_EDIT, this.onDataReloadWithEditFunc); 719 this.appBroadCast.off(BroadCastConstants.PHOTO_BROWSER_BACK_PRESS_EVENT, this.photoBrowserBackFunc); 720 721 this.controller = undefined; 722 } 723 724 getAlbumUriByUri(albumUri: string) { 725 if (albumUri && albumUri.length > 0) { 726 return albumUri; 727 } 728 729 return ''; 730 } 731 732 aboutToAppear(): void { 733 TraceControllerUtils.startTrace('PhotoBrowserAboutToAppear'); 734 Log.info(TAG, 'photoBrowser aboutToAppear'); 735 AppStorage.setOrCreate('isEditFunc', false); 736 this.geometryTransitionId = AppStorage.get<string>('geometryTransitionBrowserId') as string; 737 this.hasAppeared = true; 738 this.updateIsHorizontal(); 739 740 WindowUtil.setPreferredOrientation(AppStorage.get<common.UIAbilityContext>('photosAbilityContext') as common.UIAbilityContext, 741 window.Orientation.AUTO_ROTATION_RESTRICTED); 742 this.appBroadCast.emit('hideBar', []); 743 let param: ParamBrowser = this.browserController.browserParam as ParamBrowser; 744 let entryFromCamera = (AppStorage.get<number>('entryFromHapCamera')) as number == Constants.ENTRY_FROM_CAMERA; 745 Log.info(TAG, `photoBrowser start with entryFrom ` + JSON.stringify(entryFromCamera)); 746 if (entryFromCamera) { 747 param = { 748 pageFrom: Constants.ENTRY_FROM.CAMERA 749 } as ParamBrowser; 750 AppStorage.setOrCreate('entryFromHapCamera', Constants.ENTRY_FROM_NONE); 751 } 752 753 if (param) { 754 Log.info(TAG, `photoBrowser start with param`); 755 Log.debug(TAG, `param: ${JSON.stringify(param)}`); 756 if (param.pageFrom) { 757 this.pageFrom = param.pageFrom; 758 } 759 if (param.albumInfo) { 760 this.albumInfo = param.albumInfo; 761 this.albumUri = param.albumInfo.uri; 762 this.deviceName = param.albumInfo.deviceName; 763 } 764 if (this.pageFrom == Constants.ENTRY_FROM.CAMERA) { 765 this.dataSource = new PhotoDataSource(); 766 this.dataSource.initData(); 767 this.isFromCamera = true; 768 this.clickThumbnailTime = param.clickThumbnailTime ? param.clickThumbnailTime : 0; 769 this.albumUri = ''; 770 this.jumpSourceToMain = JumpSourceToMain.CAMERA; 771 MediaObserver.getInstance().registerObserver(this.dataObserver); 772 AppStorage.setOrCreate('entryFromHap', Constants.ENTRY_FROM_NONE); 773 } else if (this.pageFrom == Constants.ENTRY_FROM.CARD) { 774 this.dataSource = new PhotoDataSource(); 775 this.albumUri = param.albumUri; 776 this.dataSource.enableGetData(false); 777 this.dataSource.setAlbumUri(this.albumUri); 778 this.dataSource.initData(); 779 this.isFromCamera = true; 780 this.jumpSourceToMain = JumpSourceToMain.CAMERA; 781 MediaObserver.getInstance().registerObserver(this.dataObserver); 782 this.uriFromThirdPartyApp = param.uri; 783 this.currentIndex = param.index; 784 this.onGetItemIndexByUri(this.currentIndex) 785 this.isFromFACard = true; 786 this.geometryTransitionEnable = true; 787 } else if (this.pageFrom == Constants.ENTRY_FROM.RECYCLE) { 788 this.dataSource.setAlbumUri(this.albumUri); 789 this.dataSource.setAlbumDataSource 790 (AppStorage.get<MediaDataSource>(Constants.APP_KEY_PHOTO_BROWSER) as MediaDataSource); 791 } else if (this.pageFrom == Constants.ENTRY_FROM.DISTRIBUTED) { 792 this.dataSource.setDeviceId(param.albumInfo.deviceId); 793 this.dataSource.setAlbumDataSource( 794 AppStorage.get<MediaDataSource>(Constants.APP_KEY_PHOTO_BROWSER) as MediaDataSource); 795 } else if (this.pageFrom == Constants.ENTRY_FROM.VIEW_DATA) { 796 if (String(param.viewData).length === 0) { 797 Log.error(TAG, 'Invalid uri'); 798 this.setViewDataResult(false); 799 return; 800 } 801 Log.info(TAG, `Found viewIndex: ${String(param.viewDataIndex).length}`); 802 if (String(param.viewDataIndex).length > 0) { 803 Log.debug(TAG, `Found viewIndex`); 804 this.dataSource = new UriDataSource(String(param.viewData).split('?')); 805 let viewIndex = Number.parseInt(param.viewDataIndex); 806 if (Number.isNaN(viewIndex) || viewIndex <= 0 || viewIndex > String(param.viewData).split('?').length) { 807 viewIndex = 0; 808 } else { 809 viewIndex -= 1; 810 } 811 this.isFromViewDataWithThirdUri = true; 812 this.currentIndex = viewIndex; 813 param.position = viewIndex; 814 } else { 815 let uriCount = String(param.viewData).split(',').length; 816 if (uriCount > Constants.NUMBER_1) { 817 Log.error(TAG, 'Invalid uri'); 818 this.setViewDataResult(false); 819 return; 820 } 821 822 if (String(param.viewData).startsWith(PhotoDataSource.MEIDA_URL_PREFIX_STR) || 823 String(param.viewData).startsWith(PhotoDataSource.IMAGE_URL_PREFIX_STR_V10) || 824 String(param.viewData).startsWith(PhotoDataSource.VIDEO_URL_PREFIX_STR_V10) || 825 String(param.viewData).startsWith(PhotoDataSource.IMAGE_VIDEO_URL_PREFIX_STR_V10)) { 826 Log.debug(TAG, `Found media library uri`); 827 this.dataSource = new PhotoDataSource(this.albumUri); 828 this.albumUri = this.getAlbumUriByUri(param.viewDataAlbum); 829 Log.info(TAG, `album id: ${this.albumUri}`); 830 this.dataSource.enableGetData(false); 831 this.dataSource.setAlbumUri(this.albumUri); 832 this.dataSource.initData(); 833 this.isFromViewDataWithMediaUri = true; 834 this.clickThumbnailTime = 0; 835 this.jumpSourceToMain = JumpSourceToMain.CAMERA; 836 MediaObserver.getInstance().registerObserver(this.dataObserver); 837 this.uriFromThirdPartyApp = String(param.viewData); 838 this.currentIndex = 0; 839 this.dataSource.getItemIndexByUri(this.uriFromThirdPartyApp, 840 (index: number): void => this.onGetItemIndexByUri(index)); 841 // 是否显示菜单栏并且处理大数据打点 842 this.isShowMenuBigData(param.isShowMenuFromThirdView); 843 } else { 844 Log.debug(TAG, `Not found media library uri`); 845 this.dataSource = new UriDataSource(String(param.viewData).split(',')); 846 this.isFromViewDataWithThirdUri = true; 847 } 848 } 849 } else { 850 MediaObserver.getInstance().registerObserver(this.dataObserver); 851 this.dataSource.setAlbumDataSource( 852 AppStorage.get<MediaDataSource>(Constants.APP_KEY_PHOTO_BROWSER) as MediaDataSource); 853 } 854 855 this.onPhotoChanged(param.position || 0); 856 if (this.isFromFACard) { 857 this.mTransition = Constants.PHOTO_TRANSITION_ALBUM; 858 } else if (this.isFromCamera) { 859 this.mTransition = Constants.PHOTO_TRANSITION_CAMERA; 860 } else if (this.isFromViewDataWithMediaUri || this.isFromViewDataWithThirdUri) { 861 this.mTransition = Constants.PHOTO_TRANSITION_THIRD_APP; 862 } else { 863 this.mTransition = param.transition; 864 } 865 } else { 866 Log.info(TAG, `photoBrowser start without param`); 867 if (this.entryFromHap == Constants.ENTRY_FROM_FORM_ABILITY) { 868 this.pageFrom = Constants.ENTRY_FROM.CARD; 869 this.albumUri = AppStorage.get<string>('form_albumUri') as string; 870 } else { 871 this.pageFrom = Constants.ENTRY_FROM.CAMERA; 872 this.albumUri = UserFileManagerAccess.getInstance() 873 .getSystemAlbumUri(UserFileManagerAccess.IMAGE_ALBUM_SUB_TYPE); 874 } 875 AppStorage.setOrCreate('entryFromHap', Constants.ENTRY_FROM_NONE); 876 let albumDataSource: MediaDataSource = 877 AppStorage.get<MediaDataSource>(Constants.APP_KEY_PHOTO_BROWSER) as MediaDataSource; 878 if (albumDataSource) { 879 this.dataSource.setAlbumDataSource(albumDataSource); 880 } else { 881 Log.error(TAG, `Constants.APP_KEY_PHOTO_BROWSER is null, so use all album instead`); 882 this.dataSource.initData(); 883 } 884 this.isFromCamera = true; 885 this.jumpSourceToMain = JumpSourceToMain.CAMERA; 886 MediaObserver.getInstance().registerObserver(this.dataObserver); 887 this.onPhotoChanged(AppStorage.Get('form_currentIndex') || 0); 888 this.mTransition = Constants.PHOTO_TRANSITION_CAMERA; 889 } 890 891 this.checkedTransition = this.mTransition 892 893 if (this.mTransition.endsWith('ERROR')) { 894 this.checkedTransition = this.mTransition.substr(0, this.mTransition.length - 5) 895 } 896 897 this.dataSource.setBroadCast(this.broadCast); 898 this.dataSource.setBroadCastToAlbum(this.broadCast); 899 900 // register event handling 901 this.broadCast.on(PhotoConstants.TOGGLE_BAR, this.onToggleBarsFunc); 902 this.broadCast.on(PhotoConstants.HIDE_BARS, this.hideBarsFunc); 903 this.broadCast.on(PhotoConstants.SHOW_BARS, this.showBarsFunc); 904 this.broadCast.on(PhotoConstants.PULL_DOWN_START, this.pullDownStartFunc); 905 this.broadCast.on(PhotoConstants.PULL_DOWN_END, this.pullDownEndFunc); 906 this.broadCast.on(PhotoConstants.DATA_SIZE_CHANGED, this.onDataSizeChangedFunc); 907 this.broadCast.on(PhotoConstants.DATA_CONTENT_CHANGED, this.onDataContentChangedFunc); 908 this.broadCast.on(PhotoConstants.SET_FAVOR, this.setFavorFunc); 909 this.broadCast.on(PhotoConstants.RENAME, this.doRenameFunc); 910 this.broadCast.on(PhotoConstants.ROTATE, this.doRotateFunc); 911 this.broadCast.on(PhotoConstants.PULL_DOWN_START, this.pullDownStartWithEventFunc); 912 this.broadCast.on(PhotoConstants.PULL_DOWN_CANCEL, this.pullDownCancelFunc); 913 this.broadCast.on(PhotoConstants.PHOTO_BROWSER_DELETE_CONFIRM, this.onPhotoBrowserDeleteConfirmFunc); 914 this.broadCast.on(PhotoConstants.PHOTO_BROWSER_REMOVE_CONFIRM, this.onPhotoBrowserRemoveConfirmFunc); 915 this.broadCast.on(PhotoConstants.DELETE, this.doDeleteFunc); 916 this.broadCast.on(PhotoConstants.PHOTO_SHOW_STATE, this.onPhotoShowStateChangedFunc); 917 this.broadCast.on(PhotoConstants.SET_DISABLE_SWIPE, this.setSwiperDisableFunc); 918 this.broadCast.on(BroadCastConstants.ON_DATA_RELOADED_WITH_EDIT, this.onDataReloadWithEditFunc); 919 920 this.appBroadCast.on(BroadCastConstants.PHOTO_BROWSER_BACK_PRESS_EVENT, this.photoBrowserBackFunc); 921 922 interface MsgNavigation { 923 from: string; 924 fovMode: number; 925 } 926 927 let msg: MsgNavigation = { 928 from: BigDataConstants.LOCAL_MEDIA, 929 fovMode: 0 930 } 931 ReportToBigDataUtil.report(BigDataConstants.ENTER_PHOTO_BROWSER_ID, msg); 932 this.breakpointSystem.registerOrientationChange(); 933 TraceControllerUtils.finishTrace('PhotoBrowserAboutToAppear'); 934 } 935 936 onToggleBars(backgroundColorResource?: Resource): void { 937 if (this.isShowBar) { 938 this.hideBars(backgroundColorResource); 939 } else { 940 this.showBars(backgroundColorResource); 941 } 942 Log.info(TAG, `Toggle bars, isShowBar: ${this.isShowBar}`); 943 } 944 945 showBars(backgroundColorResource?: Resource): void { 946 this.backgroundColorResource = backgroundColorResource ? 947 backgroundColorResource : $r('app.color.default_background_color'); 948 if (!this.isShowBar) { 949 this.isShowBar = !this.isShowBar; 950 if (!this.isHorizontal) { 951 ScreenManager.getInstance().setSystemUi(true); 952 } 953 } else { 954 this.onlyChangeBgColor = !this.onlyChangeBgColor; 955 } 956 } 957 958 hideBars(backgroundColorResource?: Resource): void { 959 this.backgroundColorResource = backgroundColorResource ? 960 backgroundColorResource : $r('app.color.black'); 961 if (this.isShowBar) { 962 this.isShowBar = !this.isShowBar; 963 ScreenManager.getInstance().setSystemUi(false); 964 } else { 965 this.onlyChangeBgColor = !this.onlyChangeBgColor; 966 } 967 } 968 969 private pullDownStart(): void { 970 Log.info(TAG, 'pulling down start'); 971 } 972 973 private pullDownEnd(): void { 974 Log.info(TAG, 'pulling down end'); 975 if (this.isFromFACard) { 976 this.isPullDown = true; 977 } 978 this.onBackPress(); 979 } 980 981 private onDataContentChanged(): void { 982 this.reportToBigDataForCameraIn(); 983 Log.debug(TAG, `PhotoConstants.DATA_CONTENT_CHANGED`); 984 if (AppStorage.get('isEditFunc')) { 985 this.currentIndex = 0; 986 } 987 this.onPhotoChanged(this.currentIndex); 988 } 989 990 private setFavor(isFavor: boolean): void { 991 Log.debug(TAG, 'set favor !') 992 let currentPhoto = this.getCurrentPhoto(); 993 if (!isFavor) { 994 currentPhoto.isFavor = isFavor; 995 this.updateMenu(this.currentIndex); 996 } else { 997 Log.debug(TAG, 'update favor !'); 998 } 999 } 1000 1001 private doRename(result: TitleName): void { 1002 Log.info(TAG, `rename refresh: ${result.title}, ${result.displayName}`); 1003 this.updatePhotoName(result); 1004 } 1005 1006 private doRotate(result: number): void { 1007 Log.debug(TAG, `rotate finish: ${result}`); 1008 let currentPhoto = this.getCurrentPhoto(); 1009 currentPhoto.orientation = result; 1010 let temp = currentPhoto.height; 1011 currentPhoto.height = currentPhoto.width; 1012 currentPhoto.width = temp; 1013 this.dataSource.onDataChanged(this.currentIndex); 1014 this.appBroadCast.emit(BroadCastConstants.UPDATE_DATA_SOURCE, [currentPhoto]); 1015 } 1016 1017 private pullDownStartWithEvent(event: KeyEvent): void { 1018 Log.debug(TAG, `pulling down start : ${JSON.stringify(event)}`); 1019 if (this.isFromViewDataWithThirdUri) { 1020 return; 1021 } 1022 } 1023 1024 private pullDownCancel(): void { 1025 Log.info(TAG, 'pulling down cancel'); 1026 } 1027 1028 private onPhotoBrowserDeleteConfirm(): void { 1029 this.isDeleting = true; 1030 // clear temp not favorite items 1031 if (this.albumUri == UserFileManagerAccess.getInstance() 1032 .getSystemAlbumUri(UserFileManagerAccess.FAVORITE_ALBUM_SUB_TYPE)) { 1033 let key = this.theDeleteItem?.uri ?? ''; 1034 if (this.favorCacheItemsMap.has(key)) { 1035 let item = this.favorCacheItemsMap.get(key) 1036 let menuFavorContext = new MenuContext().withMediaItem(item as MediaItem).withBroadCast(this.broadCast); 1037 let menuFavorOperation = MenuOperationFactory.getInstance() 1038 .createMenuOperation(FavoriteMenuOperation, menuFavorContext); 1039 menuFavorOperation.doAction(); 1040 this.favorCacheItemsMap.delete(key); 1041 } 1042 } 1043 } 1044 1045 private onPhotoBrowserRemoveConfirm(): void { 1046 this.isDeleting = true; 1047 } 1048 1049 private doDelete(): void { 1050 Log.info(TAG, 'delete finish now update data'); 1051 } 1052 1053 private onPhotoShowStateChanged(state: boolean): void { 1054 Log.debug(TAG, 'current photo show state change'); 1055 this.currentShow = state; 1056 } 1057 1058 private setSwiperDisable(value: boolean): void { 1059 Log.info(TAG, `set swiper swipe ${value}`); 1060 this.canSwipe = value; 1061 } 1062 1063 private onDataReloadWithEdit(): void { 1064 Log.debug(TAG, 'animate to data reloaded start with edit'); 1065 try { 1066 let uri: string = AppStorage.get<string>(BroadCastConstants.PHOTO_EDIT_SAVE_URI) as string; 1067 Log.debug(TAG, `data reloaded start with edit by uri ${uri}`); 1068 if (uri) { 1069 let newIndex = this.dataSource.getDataIndexByUri(uri); 1070 let oldIndex = this.currentIndex; 1071 if (newIndex != Constants.NOT_FOUND) { 1072 // Search for the position of new image/video after edit in current 500 items succeed 1073 Log.debug(TAG, `data reloaded from ${oldIndex} move to ${newIndex}`); 1074 this.onPhotoChanged(newIndex); 1075 } else { 1076 // Search for the position of new image/video after edit in current 500 items failed 1077 Log.debug(TAG, `data reloaded from ${oldIndex} move to unknown`); 1078 this.editNewUri = uri; 1079 this.dataSource.enableGetData(false); 1080 this.currentIndex = 0; 1081 this.dataSource.getItemIndexByUri(uri, (index: number): void => this.onGetItemIndexByNewEditUri(index)); 1082 } 1083 } 1084 } catch (e) { 1085 Log.error(TAG, `ON_DATA_RELOADED_WITH_EDIT error ${e}`); 1086 } finally { 1087 this.appBroadCast.emit(BroadCastConstants.PHOTO_EDIT_SAVE_COMPLETE, []); 1088 } 1089 } 1090 1091 private photoBrowserBack(): void { 1092 Log.debug(TAG, 'hook back press from page.'); 1093 this.onBackPress(); 1094 } 1095 1096 onGetItemIndexByUri(index: number): void { 1097 Log.info(TAG, `onGetItemIndexByUri: index=${index}`); 1098 if (this.uriFromThirdPartyApp) { 1099 if (index != Constants.NOT_FOUND) { 1100 this.currentIndex = index; 1101 this.uriFromThirdPartyApp = ''; 1102 this.dataSource.enableGetData(true); 1103 this.dataSource.getData(this.currentIndex); 1104 this.dataSource.onDataReloaded(); 1105 Log.info(TAG, `Found: ${this.currentIndex}, ${this.albumUri}`); 1106 } else { 1107 if (this.albumUri === UserFileManagerAccess.getInstance() 1108 .getSystemAlbumUri(UserFileManagerAccess.TRASH_ALBUM_SUB_TYPE)) { 1109 if (this.isFromViewDataWithMediaUri || this.isFromViewDataWithThirdUri) { 1110 Log.error(TAG, `Uri from third party app is invalid`); 1111 } else if (this.isFromFACard) { 1112 Log.error(TAG, `Uri from FA is invalid`); 1113 } else { 1114 Log.error(TAG, `Uri from others is invalid`); 1115 } 1116 this.uriFromThirdPartyApp = ''; 1117 this.dataSource.enableGetData(true); 1118 this.setViewDataResult(false); 1119 } else if (this.albumUri === '') { 1120 this.resetAlbum(UserFileManagerAccess.getInstance() 1121 .getSystemAlbumUri(UserFileManagerAccess.TRASH_ALBUM_SUB_TYPE)); 1122 this.dataSource.getItemIndexByUri(this.uriFromThirdPartyApp, 1123 (index: number): void => this.onGetItemIndexByUri(index)); 1124 } else { 1125 this.resetAlbum(''); 1126 this.dataSource.getItemIndexByUri(this.uriFromThirdPartyApp, 1127 (index: number): void => this.onGetItemIndexByUri(index)); 1128 } 1129 } 1130 this.onPhotoChanged(this.currentIndex); 1131 } 1132 } 1133 1134 onGetItemIndexByNewEditUri(index: number): void { 1135 Log.info(TAG, `onGetItemIndexByNewEditUri: index=${index}`); 1136 if (this.editNewUri.length > 0) { 1137 if (index != Constants.NOT_FOUND) { 1138 Log.info(TAG, `data reloaded move to ${index}`); 1139 this.currentIndex = index; 1140 if (this.checkedTransition == Constants.PHOTO_TRANSITION_TIMELINE) { 1141 this.timelinePageIndex = this.currentIndex; // call scrollTo 1142 this.timelinePageIndex = Constants.INVALID; 1143 } else if (this.checkedTransition == Constants.PHOTO_TRANSITION_ALBUM) { 1144 this.photoGridPageIndex = this.currentIndex; // call scrollTo 1145 this.photoGridPageIndex = Constants.INVALID; 1146 } 1147 this.dataSource.enableGetData(true); 1148 this.dataSource.getData(this.currentIndex); 1149 this.dataSource.onDataReloaded(); 1150 this.editNewUri = ''; 1151 } else { 1152 Log.error(TAG, `edit new uri ${this.editNewUri} is invalid`); 1153 this.editNewUri = ''; 1154 this.currentIndex = 0; 1155 this.dataSource.enableGetData(true); 1156 } 1157 this.onPhotoChanged(this.currentIndex); 1158 } 1159 } 1160 1161 onPageShow(): void { 1162 TraceControllerUtils.startTrace('PhotoBrowseronPageShow'); 1163 Log.info(TAG, 'photoBrowser page show'); 1164 WindowUtil.setPreferredOrientation(AppStorage.get<common.UIAbilityContext>('photosAbilityContext') as common.UIAbilityContext, 1165 window.Orientation.AUTO_ROTATION_RESTRICTED); 1166 let currentPhoto = this.getCurrentPhoto(); 1167 if (currentPhoto) { 1168 this.syncPhotoName(currentPhoto).then((result) => { 1169 if (result) { 1170 this.updatePhotoName(result); 1171 this.broadCast.emit(PhotoConstants.UPDATE_PHOTO_NAME + currentPhoto?.uri, [result.title]); 1172 } 1173 }); 1174 } 1175 this.updateActionBar(this.currentIndex); 1176 if (!this.isHorizontal) { 1177 ScreenManager.getInstance().setSystemUi(true); 1178 } 1179 this.appBroadCast.emit(BroadCastConstants.THIRD_ROUTE_PAGE, []); 1180 this.appBroadCast.emit(BroadCastConstants.PHOTO_BROWSER_ACTIVE, [true, this.checkedTransition]); 1181 this.broadCast.emit(BroadCastConstants.CHANGE_SWIPER_DURATION, [400]); 1182 this.viewTime = Date.now(); 1183 let params: Params = router.getParams() as Params; 1184 if (params != null && params.pageType != null && this.backFromCopy) { 1185 Log.debug(TAG, `MediaOperation back ${JSON.stringify(params)}`) 1186 let menuContext = new MenuContext(); 1187 let menuOperation: MenuOperation | null = null; 1188 if (currentPhoto == undefined) { 1189 Log.error(TAG, 'MediaOperation currentPhoto is undefined'); 1190 return; 1191 } 1192 if (params.pageType === MediaOperationType.Move) { 1193 let onMoveEndFunc = async (err: Error, count: number, total: number): Promise<void> => { 1194 await this.onMoveEnd(err as Object, count, total); 1195 } 1196 menuContext.withMediaItem(currentPhoto) 1197 .withBroadCast(this.broadCast) 1198 .withTargetAlbumName(params.albumName) 1199 .withAlbumUri(params.albumUri) 1200 .withOperationEndCallback(onMoveEndFunc); 1201 menuOperation = MenuOperationFactory.getInstance().createMenuOperation(MoveMenuOperation, menuContext); 1202 AppStorage.setOrCreate<string | undefined>(Constants.APP_KEY_NEW_ALBUM_SOURCE, this.albumInfo?.uri); 1203 } else if (params.pageType === MediaOperationType.Remove) { 1204 let onMoveEndFunc = async (err: Error, count: number, total: number): Promise<void> => { 1205 await this.onMoveEnd(err as Object, count, total); 1206 } 1207 menuContext.withMediaItem(currentPhoto) 1208 .withBroadCast(this.broadCast) 1209 .withTargetAlbumName(params.albumName) 1210 .withAlbumUri(params.albumUri) 1211 .withOperationEndCallback(onMoveEndFunc); 1212 menuOperation = MenuOperationFactory.getInstance().createMenuOperation(RemoveMenuOperation, menuContext); 1213 AppStorage.setOrCreate<string | undefined>(Constants.APP_KEY_NEW_ALBUM_SOURCE, this.albumInfo?.uri); 1214 } else if (params.pageType === MediaOperationType.Add) { 1215 // "添加到"不需要设置源相册 1216 let onCopyEndFunc = (err: Error, count: number, total: number): void => { 1217 this.onCopyEnd(err as Object, count, total); 1218 } 1219 menuContext.withMediaItem(currentPhoto) 1220 .withBroadCast(this.broadCast) 1221 .withTargetAlbumName(params.albumName) 1222 .withAlbumUri(params.albumUri) 1223 .withOperationEndCallback(onCopyEndFunc); 1224 menuOperation = MenuOperationFactory.getInstance().createMenuOperation(AddMenuOperation, menuContext); 1225 this.appBroadCast.emit(BroadCastConstants.PHOTO_BROWSER_ACTIVE, [false, this.checkedTransition]); 1226 } 1227 1228 if (menuOperation != null) { 1229 menuOperation.doAction(); 1230 } 1231 } 1232 this.backFromCopy = false; 1233 TraceControllerUtils.finishTrace('PhotoBrowseronPageShow'); 1234 } 1235 1236 onPageHide(): void { 1237 Log.info(TAG, `call onPageHide`); 1238 this.appBroadCast.emit(BroadCastConstants.PHOTO_BROWSER_ACTIVE, [false, this.checkedTransition]); 1239 WindowUtil.setPreferredOrientation(AppStorage.get<common.UIAbilityContext>('photosAbilityContext') as common.UIAbilityContext, 1240 window.Orientation.UNSPECIFIED); 1241 } 1242 1243 onMediaLibDataChange(changeType: string): void { 1244 Log.info(TAG, `onMediaLibDataChange type: ${changeType}`); 1245 this.dataSource.onChange(changeType); 1246 } 1247 1248 build() { 1249 Stack({ alignContent: Alignment.TopStart }) { 1250 PhotoBrowserComponentBg({ isShowBar: $isShowBar, isFromPhotoBrowser: true }) 1251 .opacity(this.geometryOpacity) 1252 .transition(TransitionEffect.opacity(0)) 1253 1254 PhotoSwiper({ 1255 dataSource: this.dataSource, 1256 mTransition: this.mTransition, 1257 swiperController: this.controller, 1258 onPhotoChanged: (index: number): void => this.onPhotoChanged(index), 1259 geometryTransitionEnable: this.geometryTransitionEnable, 1260 broadCast: $broadCast, 1261 isRunningAnimation: $isRunningAnimation, 1262 isFromFACard: this.isFromFACard 1263 }) 1264 1265 if (!this.isFromViewDataWithThirdUri) { 1266 PhotoBrowserActionBar({ 1267 onMenuClicked: (action: Action): void => this.onMenuClicked(action), 1268 }) 1269 .opacity(this.geometryOpacity) 1270 .transition(TransitionEffect.opacity(0)) 1271 1272 if (!this.isHorizontal) { 1273 PhotoBrowserToolBar({ 1274 onMenuClicked: (action: Action): void => this.onMenuClicked(action), 1275 isFromPhotoBrowser: true 1276 }) 1277 .opacity(this.geometryOpacity) 1278 .transition(TransitionEffect.opacity(0)) 1279 .markAnchor({ x: Constants.PERCENT_0, y: Constants.PERCENT_100 }) 1280 .position({ x: Constants.PERCENT_0, y: Constants.PERCENT_100 }) 1281 } 1282 1283 CustomDialogView({ broadCast: $broadCast }) 1284 .opacity(this.geometryOpacity) 1285 .transition(TransitionEffect.opacity(0)) 1286 1287 } else { 1288 PhotoBrowserActionBar({ 1289 onMenuClicked: (action: Action): void => this.onMenuClicked(action), 1290 }) 1291 .opacity(this.geometryOpacity) 1292 .transition(TransitionEffect.opacity(0)) 1293 } 1294 } 1295 } 1296 1297 private setViewDataResult(result: boolean): void { 1298 if (!this.isFromViewDataWithMediaUri && !this.isFromViewDataWithThirdUri) { 1299 return; 1300 } 1301 1302 let resultCode = 0; 1303 if (result == false) { 1304 resultCode = -1; 1305 } 1306 1307 let abilityResult: ability.AbilityResult = { 1308 resultCode: resultCode, 1309 want: {} 1310 }; 1311 1312 let context: common.UIAbilityContext = AppStorage.get<common.UIAbilityContext>('photosAbilityContext') as common.UIAbilityContext; 1313 context.terminateSelfWithResult(abilityResult).then((result: void) => { 1314 Log.info(TAG, `terminateSelfWithResult result: ${result}`); 1315 }); 1316 } 1317 1318 private downLoad(): void { 1319 Log.info(TAG, 'downLoad run'); 1320 let menuContext = new MenuContext(); 1321 let menuOperation: MenuOperation; 1322 let currentPhoto = this.getCurrentPhoto(); 1323 let onDownloadEndFunc = async (err: Error, count: number, total: number): Promise<void> => { 1324 await this.onDownloadEnd(err as Object, count, total); 1325 } 1326 if (currentPhoto == undefined) { 1327 Log.error(TAG, 'MediaOperation currentPhoto is undefined'); 1328 return; 1329 } 1330 menuContext 1331 .withMediaItem(currentPhoto) 1332 .withBroadCast(this.broadCast) 1333 .withRemoteDevice('0') // TODO input deviceId 1334 .withOperationEndCallback(onDownloadEndFunc) 1335 menuOperation = MenuOperationFactory.getInstance().createMenuOperation(AddMenuOperation, menuContext); 1336 this.appBroadCast.emit(BroadCastConstants.PHOTO_BROWSER_ACTIVE, [false, this.checkedTransition]); 1337 menuOperation.doAction(); 1338 } 1339 1340 private reportToBigDataForPhotoSlide(index: number): void { 1341 let currentPhoto = this.getCurrentPhoto(); 1342 if (currentPhoto && index != this.currentIndex && this.viewTime != 0) { 1343 let currentTime = Date.now(); 1344 interface Msg { 1345 type: string; 1346 duration: number; 1347 } 1348 let msg: Msg = { 1349 type: currentPhoto.mediaType == UserFileManagerAccess.MEDIA_TYPE_VIDEO ? 1350 BigDataConstants.VIDEO : BigDataConstants.NORMAL_PHOTO, 1351 duration: (currentTime - this.viewTime) 1352 } 1353 ReportToBigDataUtil.report(BigDataConstants.PHOTO_BROWSER_SLIDE_ID, msg); 1354 this.viewTime = Date.now(); 1355 } 1356 } 1357 1358 private reportToBigDataForCameraIn(): void { 1359 if (this.clickThumbnailTime == 0 || !this.isFromCamera) { 1360 return; 1361 } 1362 interface Msg { 1363 clickThumbnailTime: number; 1364 showSinglePhoto: number; 1365 fileName?: string; 1366 } 1367 let msg: Msg = { 1368 clickThumbnailTime: this.clickThumbnailTime, 1369 showSinglePhoto: Date.now() 1370 } 1371 let fileName = ReportToBigDataUtil.getFileNameOfPhotoTakenByCamera(this.getPhotoByIndex(0)); 1372 ReportToBigDataUtil.setFileNameProperty(msg, fileName); 1373 ReportToBigDataUtil.report(BigDataConstants.BROWSE_PHOTO_FROM_CAMERA_ID, msg); 1374 this.clickThumbnailTime = 0; 1375 } 1376 1377 private async syncPhotoName(currentPhoto: MediaItem): Promise<TitleName> { 1378 Log.debug(TAG, 'syncPhotoName start'); 1379 let renameResult: TitleName = {title: '', displayName: ''}; 1380 let fileAsset = await this.dataSource?.getDataByUri(currentPhoto?.uri); 1381 if (fileAsset) { 1382 renameResult = { 1383 title: fileAsset.get(UserFileManagerAccess.FILE_KEY_TITLE.toString()) as string, 1384 displayName: fileAsset.displayName 1385 }; 1386 } else { 1387 let key: string = 'renameResult' + currentPhoto?.uri; 1388 renameResult = AppStorage.get<TitleName>(key) as TitleName; 1389 AppStorage.delete(key); 1390 } 1391 Log.debug(TAG, `syncPhotoName end, renameResult : ${JSON.stringify(renameResult)}`); 1392 return renameResult; 1393 } 1394} 1395