1/* 2 * Copyright (c) 2022-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 { Log } from '../../utils/Log'; 17import { MenuContext } from './MenuContext'; 18import { ProcessMenuOperation } from './ProcessMenuOperation'; 19import { MediaOperationType } from '../../model/common/MediaOperationType'; 20import { SelectManager } from '../../model/browser/SelectManager'; 21import { BroadCastConstants } from '../../model/common/BroadCastConstants'; 22import { TraceControllerUtils } from '../../utils/TraceControllerUtils'; 23import type { FileAsset } from '../../access/UserFileManagerAccess'; 24import { Album, UserFileManagerAccess } from '../../access/UserFileManagerAccess'; 25import { Constants } from '../../model/common/Constants'; 26import { BigDataConstants, ReportToBigDataUtil } from '../../utils/ReportToBigDataUtil'; 27import { BrowserOperationFactory } from '../../interface/BrowserOperationFactory'; 28 29const TAG: string = 'common_MoveMenuOperation'; 30 31export class MoveMenuOperation extends ProcessMenuOperation { 32 albumUri: string; 33 albumName: string; 34 35 constructor(menuContext: MenuContext) { 36 super(menuContext); 37 this.albumUri = menuContext.albumUri; 38 } 39 40 doAction(): void { 41 Log.info(TAG, 'move doAction'); 42 if (this.menuContext == null) { 43 Log.error(TAG, 'menuContext is null, return'); 44 return; 45 } 46 47 if (this.menuContext.selectManager) { 48 let selectManager: SelectManager = this.menuContext.selectManager; 49 if (selectManager == null || selectManager == undefined) { 50 Log.error(TAG, 'selectManager is null, return'); 51 return; 52 } 53 54 this.count = selectManager.getSelectedCount(); 55 if (this.count <= 0) { 56 Log.error(TAG, 'count <= 0, return'); 57 return; 58 } 59 let msg = { 60 'Type': BigDataConstants.MEDIA_MOVE, 61 'Count': this.count 62 }; 63 ReportToBigDataUtil.report(BigDataConstants.ALBUM_OPERATION_ID, msg); 64 65 this.onOperationEnd = this.menuContext.onOperationEnd; 66 selectManager.getSelection(this); 67 68 let onOperationStart: Function = this.menuContext.onOperationStart; 69 onOperationStart && onOperationStart(); 70 } else { 71 this.count = 1; 72 let mediaItem = this.menuContext.mediaItem; 73 if (mediaItem == null) { 74 Log.error(TAG, 'mediaItem is null, return'); 75 return; 76 } 77 this.onOperationEnd = this.menuContext.onOperationEnd; 78 this.callback([mediaItem.uri]); 79 } 80 81 this.menuContext.broadCast.emit(BroadCastConstants.SHOW_PROGRESS_DIALOG, 82 [$r('app.string.move_progress_message', this.albumName), MediaOperationType.Move, this.cancelFunc.bind(this)] 83 ); 84 } 85 86 callback(uris: string[]): void { 87 this.uris = uris; 88 this.processOperation(); 89 } 90 91 // Move a batch of data 92 requestOneBatchOperation(): void { 93 if (this.isCancelled) { 94 return; 95 } 96 this.currentBatch++; 97 let startIndex = (this.currentBatch - 1) * this.BATCH_SIZE; 98 let endIndex = this.currentBatch * this.BATCH_SIZE; 99 let batchUris: string[] = this.uris.slice(startIndex, Math.min(endIndex, this.uris.length)); 100 101 if (batchUris[0] == undefined) { 102 this.onOperateContinue(); 103 return; 104 } 105 TraceControllerUtils.startTraceWithTaskId('getFileCopyOrMoveInfo', this.currentBatch); 106 this.getFileAddOrMoveInfo(batchUris[0]).then((fileAsset: FileAsset) => { 107 TraceControllerUtils.finishTraceWithTaskId('getFileCopyOrMoveInfo', this.currentBatch); 108 this.move(fileAsset); 109 }) 110 } 111 112 async move(sourceAsset: FileAsset): Promise<void> { 113 Log.debug(TAG, 'move file.mediaType:' + JSON.stringify(sourceAsset.fileType)); 114 try { 115 TraceControllerUtils.startTraceWithTaskId('move', this.currentBatch); 116 let sourceAlbumUri: string = AppStorage.get(Constants.APP_KEY_NEW_ALBUM_SOURCE); 117 let targetAlbum: Album = await UserFileManagerAccess.getInstance().getAlbumByUri(this.albumUri); 118 await targetAlbum.addPhotoAssets([sourceAsset]); 119 120 let sourceAlbum: Album = await UserFileManagerAccess.getInstance().getAlbumByUri(sourceAlbumUri); 121 await sourceAlbum.removePhotoAssets([sourceAsset]); 122 let operationImpl = BrowserOperationFactory.getFeature(BrowserOperationFactory.TYPE_PHOTO); 123 await operationImpl.deleteTrash([sourceAsset]); 124 125 TraceControllerUtils.finishTraceWithTaskId('move', this.currentBatch); 126 this.onCompleted(); 127 } catch (error) { 128 let msg = { 129 'Type': BigDataConstants.MEDIA_MOVE_ERROR, 130 'errMsg': JSON.stringify(error) 131 }; 132 ReportToBigDataUtil.errEventReport(BigDataConstants.ALBUM_OPERATION_ERROR_ID, msg); 133 Log.error(TAG, `move error: ${error}`) 134 this.onError(); 135 } 136 } 137 138 cancelFunc(): void { 139 Log.info(TAG, `progress cancel`); 140 this.onOperatePause(); 141 let cancelMessage = $r('app.string.move_cancel_message', `${this.getExpectProgress().toString()}%`); 142 this.menuContext.broadCast && this.menuContext.broadCast.emit(BroadCastConstants.CANCEL_OPERATE, 143 [cancelMessage, this.onOperateContinue.bind(this), this.onOperateCancelled.bind(this)]); 144 } 145 146 // Move cancel callback 147 onOperateContinue(): void { 148 Log.info(TAG, 'Operate Continue'); 149 this.isPause = false; 150 this.cyclicOperation(); 151 } 152}