• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2023 Shenzhen Kaihong Digital Industry Development 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 photoAccessHelper from '@ohos.file.photoAccessHelper';
17import { AsyncCallback } from './AsyncCallback';
18import { Log } from '../utils/Log';
19import { MenuOperationCallback } from './MenuOperationCallback';
20import { MenuOperation } from './MenuOperation';
21import { MenuContext } from './MenuContext';
22import { BroadcastConstants } from '../constants/BroadcastConstants';
23import { SimpleAlbumDataItem } from '../common/SimpleAlbumDataItem';
24import { userFileModel } from '../base/UserFileModel';
25
26export enum FindSameOperation {
27  NONE,
28  REPLACE,
29  SKIP
30}
31
32export interface Assets {
33  sourceAsset: photoAccessHelper.PhotoAsset,
34  targetAsset: photoAccessHelper.PhotoAsset
35}
36
37const TAG = 'ProcessMenuOperation';
38
39export class ProcessMenuOperation implements MenuOperation, AsyncCallback<String[]>, MenuOperationCallback {
40  // Number of data operated in a batch
41  readonly BATCH_SIZE: number = 1;
42
43  // Maximum progress
44  readonly MAX_PROGRESS: number = 100;
45  items: Object[] = [];
46  menuContext: MenuContext;
47  uris: string[];
48  count: number;
49  onOperationEnd: Function;
50
51  // Total batches operated
52  totalBatches: number;
53
54  // Currently operated batch
55  currentBatch: number = 0;
56  successBatch: number = 0;
57  isCancelled: boolean = false;
58  startTime: number;
59  isPause: boolean = false;
60  isError: boolean = false;
61  findSameOperation: number = FindSameOperation.NONE;
62  requestTime: number;
63
64  constructor(menuContext: MenuContext) {
65    this.menuContext = menuContext;
66    this.requestTime = Date.now();
67  }
68
69  doAction(): void {
70  }
71
72  // Asynchronous callback for getSelection
73  callback(uris: string[]): void {
74    this.callbackBindImpl(uris);
75  }
76
77  protected callbackBindImpl(uris: string[]): void {
78  }
79
80  onCompleted(): void {
81    Log.info(TAG, 'onCompleted ' + this.isPause);
82    this.successBatch++;
83    if (!this.isPause) {
84      this.cyclicOperation();
85    }
86  }
87
88  onError(): void {
89    Log.error(TAG, 'Operate the ' + this.currentBatch + ' batch data error, total ' + this.totalBatches + ' batches');
90    this.isError = true;
91    this.cyclicOperation();
92  }
93
94  // Start processing operation
95  processOperation(): void {
96    Log.info(TAG, 'processOperation start');
97    let length = this.items.length;
98    Log.info(TAG, 'selected count: ' + this.count + ', uris length: ' + length);
99    // Batch deletion
100    this.totalBatches = Math.floor(length / this.BATCH_SIZE) + (((length % this.BATCH_SIZE) ? 1 : 0) as number);
101    Log.info(TAG, 'The count to be operate is ' + length + ', operate in ' + this.totalBatches + ' batches');
102    if (this.isCancelled) {
103      this.isCancelled = false;
104    }
105    this.startTime = Date.now();
106
107    this.requestOneBatchOperation();
108  }
109
110  // Batch circular deletion
111  cyclicOperation(): void {
112    Log.info(TAG, 'cyclicOperation');
113    this.menuContext.broadCast.emit(BroadcastConstants.UPDATE_PROGRESS, [this.getExpectProgress(), this.currentBatch]);
114
115    if (this.isCancelled) {
116      this.onProcessDone();
117    }
118
119    if (this.currentBatch >= this.totalBatches || this.isError) {
120      this.onProcessDone();
121    } else {
122      this.requestOneBatchOperation();
123    }
124  }
125
126  // Operate a batch of data
127  requestOneBatchOperation(): void {
128  }
129
130  onProcessDone(): void {
131    this.menuContext.broadCast.emit(BroadcastConstants.UPDATE_PROGRESS, [100]);
132    this.findSameOperation = FindSameOperation.NONE;
133    if (this.startTime != null) {
134      let operateCount = this.currentBatch >= this.totalBatches ? this.count : this.currentBatch * this.BATCH_SIZE;
135      let costTime = Date.now() - this.startTime;
136      Log.debug(TAG, 'process data operate done, operate ' + operateCount + ' items, cost time ' + costTime +
137      ' ms, average ' + (costTime / operateCount) + ' ms/item.');
138    }
139    this.isCancelled = false;
140    if (this.onOperationEnd != null) this.onOperationEnd(this.isError, this.successBatch, this.count);
141  }
142
143  // Operate cancel callback
144  onOperateCancelled(): void {
145    this.onOperateCancelledBindImpl();
146  }
147
148  protected onOperateCancelledBindImpl(): void {
149    Log.info(TAG, 'Operate Cancel');
150    this.isCancelled = true;
151    this.onProcessDone();
152  }
153
154  // Operate cancel callback
155  onOperatePause(): void {
156    Log.info(TAG, 'Operate Pause');
157    this.isPause = true;
158  }
159
160  // Calculate the operation progress according to the batch
161  getExpectProgress(): number {
162    Log.info(TAG, 'getExpectProgress');
163    let progress = Math.min(
164      Math.floor(this.MAX_PROGRESS * this.currentBatch * this.BATCH_SIZE / this.count), this.MAX_PROGRESS);
165    return progress;
166  }
167
168  setFindSameOperation(newOperation: number): void {
169    this.setFindSameOperationBindImpl(newOperation);
170  }
171
172  protected setFindSameOperationBindImpl(newOperation: number): void {
173    Log.info(TAG, 'setFindSameOperation ' + newOperation);
174    this.findSameOperation = newOperation;
175  }
176}
177