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