1/* 2 * Copyright (c) 2022 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 */ 15import MediaLib from '@ohos.multimedia.mediaLibrary'; 16import mediaModel from '../model/MediaModel'; 17import { Log } from '../utils/Log'; 18import { MenuContext } from './MenuContext'; 19import { ProcessMenuOperation, FindSameOperation } from './ProcessMenuOperation'; 20import { MediaOperationType } from '../data/MediaOperationType'; 21import { BroadcastConstants } from '../constants/BroadcastConstants'; 22import { startTraceWithTaskId, finishTraceWithTaskId } from '../utils/TraceControllerUtils'; 23import { ItemDataSource } from '../vm/ItemDataSource'; 24import { MediaDataItem } from '../data/MediaDataItem'; 25import { SimpleAlbumDataItem } from '../data/SimpleAlbumDataItem'; 26 27const TAG = "MoveMenuOperation" 28 29export class MoveMenuOperation extends ProcessMenuOperation { 30 albumInfo: SimpleAlbumDataItem; 31 32 constructor(menuContext: MenuContext) { 33 super(menuContext); 34 this.albumInfo = menuContext.albumInfo; 35 } 36 37 doAction(): void { 38 Log.info(TAG, 'move doAction'); 39 if (this.menuContext == null) { 40 Log.warn(TAG, 'menuContext is null, return'); 41 return; 42 } 43 44 let dataSource: ItemDataSource = this.menuContext.dataSource; 45 if (dataSource == null) { 46 this.count = this.menuContext.items.length; 47 } else { 48 this.count = dataSource.getSelectedCount(); 49 } 50 if (this.count <= 0) { 51 Log.warn(TAG, 'count <= 0, return'); 52 return; 53 } 54 55 this.onOperationEnd = this.menuContext.onOperationEnd; 56 let onOperationStart = this.menuContext.onOperationStart; 57 58 onOperationStart && onOperationStart(); 59 60 this.menuContext.broadCast.emit( 61 BroadcastConstants.SHOW_PROGRESS_DIALOG, [$r('app.string.move_progress_message', this.albumInfo.displayName), 62 MediaOperationType.Move, this.cancelFunc.bind(this)]); 63 64 if (dataSource == null) { 65 this.items = this.menuContext.items; 66 } else { 67 this.items = dataSource.getSelectedItems(); 68 } 69 this.processOperation(); 70 } 71 72 requestOneBatchOperation() { 73 let item = this.items[this.currentBatch++] as MediaDataItem; 74 this.moveOne(item); 75 } 76 77 private async moveOne(item: MediaDataItem) { 78 let fileAsset = await item.loadFileAsset(); 79 let assets = await this.getFileCopyOrMoveInfo(fileAsset, this.albumInfo); 80 if (assets.targetAsset) { 81 if (assets.targetAsset.uri == assets.sourceAsset.uri) { 82 Log.info(TAG, 'move same fileAsset'); 83 this.onOperateContinue(); 84 return; 85 } 86 Log.info(TAG, 'show find same file dialog'); 87 switch (this.findSameOperation) { 88 case FindSameOperation.NONE: 89 this.menuContext.broadCast.emit(BroadcastConstants.FIND_SAME_FILE_DIALOG, 90 [assets, this.count, () => { 91 this.move(assets.sourceAsset, this.albumInfo.relativePath, assets.targetAsset); 92 }, this.onOperateContinue.bind(this), this.onOperateCancelled.bind(this), 93 this.setFindSameOperation.bind(this)]); 94 break; 95 case FindSameOperation.REPLACE: 96 this.move(assets.sourceAsset, this.albumInfo.relativePath, assets.targetAsset); 97 break; 98 case FindSameOperation.SKIP: 99 this.onOperateContinue(); 100 break; 101 default: 102 Log.warn(TAG, `findSameOperation is error ${this.findSameOperation}`); 103 break; 104 } 105 } else { 106 this.move(assets.sourceAsset, this.albumInfo.relativePath); 107 } 108 } 109 110 async move(file: MediaLib.FileAsset, path: string, targetFile?) { 111 startTraceWithTaskId('move', this.currentBatch); 112 try { 113 if (targetFile) { 114 await mediaModel.deleteOne(targetFile.uri); 115 } 116 file.relativePath = path; 117 file.commitModify(); 118 finishTraceWithTaskId('move', this.currentBatch); 119 this.onCompleted(); 120 } catch (error) { 121 Log.error(TAG, `move error: ${error}`) 122 this.onError(); 123 } 124 } 125 126 cancelFunc(): void { 127 Log.info(TAG, `progress cancel`); 128 this.onOperatePause(); 129 let cancelMessage = $r('app.string.move_cancel_message', this.getExpectProgress().toString()); 130 this.menuContext.broadCast && this.menuContext.broadCast.emit(BroadcastConstants.CANCEL_OPERATE, 131 [cancelMessage, this.onOperateContinue.bind(this), this.onOperateCancelled.bind(this)]); 132 } 133 134 // Move cancel callback 135 onOperateContinue(): void { 136 Log.info(TAG, 'Operate Continue'); 137 this.isPause = false; 138 this.cyclicOperation(); 139 } 140}