• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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}