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 { SelectManager } from '../../model/browser/SelectManager'; 18import { MenuContext } from './MenuContext'; 19import { BrowserOperationFactory } from '../../interface/BrowserOperationFactory'; 20import { BroadCastConstants } from '../../model/common/BroadCastConstants'; 21import { AlbumDefine } from '../../model/browser/AlbumDefine'; 22import { ProcessMenuOperation } from './ProcessMenuOperation'; 23import { TraceControllerUtils } from '../../utils/TraceControllerUtils'; 24import { BigDataConstants, ReportToBigDataUtil } from '../../utils/ReportToBigDataUtil'; 25import { Constants } from '../../model/common/Constants'; 26import { FileAsset, UserFileManagerAccess } from '../../access/UserFileManagerAccess'; 27 28const TAG: string = 'common_BatchDeleteMenuOperation'; 29 30export class BatchDeleteMenuOperation extends ProcessMenuOperation { 31 private isTrash = true; 32 // Number of data operated in a batch 33 readonly BATCH_SIZE: number = 100; 34 35 constructor(menuContext: MenuContext) { 36 super(menuContext); 37 //初始化绑定this指向 38 this.callback = this.callback.bind(this) 39 } 40 41 setConfirmText(): void { 42 if (!this.isTrash) { 43 AppStorage.setOrCreate<Resource>(Constants.CONFIRM_TEXT_KEY, $r('app.string.dialog_delete_permanently')); 44 } else { 45 AppStorage.setOrCreate<Resource>(Constants.CONFIRM_TEXT_KEY, $r('app.string.dialog_delete')); 46 } 47 } 48 49 doAction(): void { 50 if (this.menuContext == null) { 51 Log.error(TAG, 'menuContext is null, return'); 52 return; 53 } 54 if (this.menuContext.albumInfo && this.menuContext.albumInfo.isTrashAlbum) { 55 this.isTrash = false; 56 } 57 let selectManager: SelectManager = this.menuContext.selectManager; 58 if (selectManager == null) { 59 Log.error(TAG, 'selectManager is null, return'); 60 return; 61 } 62 this.count = selectManager.getSelectedCount(); 63 if (this.count <= 0) { 64 Log.error(TAG, 'count <= 0, return'); 65 return; 66 } 67 68 this.confirmCallback = this.confirmCallback.bind(this); 69 this.cancelCallback = this.cancelCallback.bind(this); 70 this.setConfirmText(); 71 if (this.menuContext.albumInfo && this.menuContext.albumInfo.isTrashAlbum) { 72 if (selectManager.isAllSelected) { 73 this.menuContext.broadCast.emit(BroadCastConstants.SHOW_DELETE_DIALOG, 74 [$r('app.string.recycleAlbum_delete_all_images_message', this.count), 75 this.confirmCallback, this.cancelCallback]); 76 } else if (this.count === 1) { 77 this.menuContext.broadCast.emit(BroadCastConstants.SHOW_DELETE_DIALOG, 78 [$r('app.plural.recycleAlbum_delete_message', this.count, this.count), 79 this.confirmCallback, this.cancelCallback]); 80 } else { 81 this.menuContext.broadCast.emit(BroadCastConstants.SHOW_DELETE_DIALOG, 82 [$r('app.plural.recycleAlbum_delete_multiple_images_message', this.count, this.count), 83 this.confirmCallback, this.cancelCallback]); 84 } 85 } else { 86 this.menuContext.broadCast.emit(BroadCastConstants.SHOW_DELETE_DIALOG, 87 [selectManager.isAllSelected ? $r('app.string.recycle_all_files_tips') : 88 (this.count == 1 ? $r('app.string.recycle_single_file_tips') : 89 $r('app.string.recycle_files_tips', this.count)), this.confirmCallback, this.cancelCallback]); 90 } 91 } 92 93 // Asynchronous callback for getSelection 94 callback(uris: string[]): void { 95 if (this.isCancelled) { 96 return; 97 } 98 this.uris = uris; 99 this.processOperation(); 100 } 101 102 // Delete a batch of data 103 async requestOneBatchOperation(): Promise<void> { 104 Log.info(TAG, `requestOneBatchOperation`); 105 if (this.isCancelled) { 106 return; 107 } 108 this.currentBatch++; 109 let startIndex: number = (this.currentBatch - 1) * this.BATCH_SIZE; 110 let endIndex: number = Math.min(this.currentBatch * this.BATCH_SIZE, this.count); 111 let batchUris: Array<string> = new Array(); 112 for (let index = startIndex; index < endIndex; index++) { 113 batchUris.push(this.uris[index]); 114 } 115 116 let operationImpl = BrowserOperationFactory.getFeature(BrowserOperationFactory.TYPE_PHOTO); 117 if (this.menuContext.albumInfo && this.menuContext.albumInfo.isTrashAlbum) { 118 TraceControllerUtils.startTraceWithTaskId('delete', this.currentBatch); 119 let fileAssets = new Array<FileAsset>(); 120 let fileItem = await UserFileManagerAccess.getInstance().getTrashAssetByUri(batchUris[0]); 121 fileAssets.push(fileItem); 122 operationImpl.deleteTrash(fileAssets).then(() => { 123 TraceControllerUtils.finishTraceWithTaskId('delete', this.currentBatch) 124 this.onCompleted() 125 }).catch((error) => { 126 Log.error(TAG, `delete error: ${error}`); 127 this.onError(); 128 }) 129 } else { 130 TraceControllerUtils.startTraceWithTaskId('trash', this.currentBatch) 131 operationImpl.trash(batchUris).then(() => { 132 TraceControllerUtils.finishTraceWithTaskId('trash', this.currentBatch) 133 this.onCompleted() 134 }).catch((error) => { 135 Log.error(TAG, `delete error: ${error}`); 136 this.onError(); 137 }) 138 } 139 } 140 141 confirmCallback(): void { 142 Log.info(TAG, 'Batch delete confirm'); 143 // 1. Variable initialization 144 this.onOperationEnd = this.menuContext.onOperationEnd; 145 // 2. selectManager gets the URI of the data and starts processing deletion in the callback 146 if (this.menuContext.albumInfo && this.menuContext.albumInfo.isTrashAlbum) { 147 this.menuContext.selectManager.getDeleteSelection(this); 148 } else { 149 this.menuContext.selectManager.getSelection(this); 150 } 151 152 // 3. onDeleteStart exit selection mode 153 let onOperationStart: Function = this.menuContext.onOperationStart; 154 onOperationStart && onOperationStart(); 155 let msg = { 156 'type': BigDataConstants.DELETE_LOCAL_ONLY, 157 'FovMode': 0 158 } 159 ReportToBigDataUtil.report(BigDataConstants.DELETE_TYPE_ID, msg); 160 161 this.menuContext.broadCast.emit(BroadCastConstants.DELETE_PROGRESS_DIALOG, 162 [$r('app.string.action_delete'), this.count]); 163 } 164 165 cancelCallback(): void { 166 Log.info(TAG, 'Batch delete cancel'); 167 this.setConfirmText(); 168 if (!this.menuContext.fromSelectMode) { 169 this.menuContext.selectManager.deSelectAll(); 170 } 171 } 172}