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