1/*
2 * Copyright (c) 2021-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 { getFileIcon, randomId, formatSuffix } from '../../base/utils/Tools';
17import { MILLISECOND } from '../../base/constants/Constant';
18import fileAccess from '@ohos.file.fileAccess';
19import { THUMBNAIL_SIZE } from '../../base/constants/UiConstant';
20import { MimeType } from './MimeType';
21import { BasicDataSource } from './BasicDataSource';
22import AbilityCommonUtil, { ResultCodePicker } from '../../base/utils/AbilityCommonUtil';
23import { FileUtil } from '../../base/utils/FileUtil';
24import { ArrayUtil } from '../../base/utils/ArrayUtil';
25import { StartModeOptions } from '../../base/model/StartModeOptions';
26
27export class BreadData {
28  public title: string;
29  public url: string;
30  public fileIterator?: fileAccess.FileInfo;
31
32  constructor(obj) {
33    this.title = obj.title;
34    this.url = obj.url;
35    this.fileIterator = obj.fileIterator;
36  }
37}
38
39export class FileDataSource extends BasicDataSource {
40  private dataArray: FilesData[] = [];
41  public dataCount: number = 0;
42
43  public totalCount(): number {
44    return this.dataArray.length;
45  }
46
47  public getDataArray(): FilesData[] {
48    return this.dataArray;
49  }
50
51  public getFileList(): FilesData[] {
52    return this.dataArray.filter(item =>!item.isFolder);
53  }
54
55  public setData(data: FilesData[]): void {
56    this.dataArray = [...data];
57    this.dataCount = this.dataArray.length;
58    this.notifyDataReload();
59  }
60
61  public getData(index: number): FilesData {
62    return this.dataArray[index];
63  }
64
65  public selectAll(isSelected): void {
66    this.dataArray.forEach(item => {
67      item.isChecked = isSelected;
68    });
69  }
70
71  public getIndex(uri): number {
72    return this.dataArray.findIndex(item => item.uri === uri);
73  }
74
75  public getSelectedFileList(): FilesData[] {
76    return this.dataArray.filter(item => item.isChecked);
77  }
78
79  public replaceData(index, data: FilesData): void {
80    this.dataArray.splice(index, 1, data);
81    this.notifyDataChange(index);
82  }
83
84  public addData(index: number, data: FilesData): void {
85    this.dataArray.splice(index, 0, data);
86    this.dataCount = this.dataArray.length;
87    this.notifyDataAdd(index);
88  }
89
90  public pushData(data: FilesData): void {
91    this.dataArray.push(data);
92    this.dataCount = this.dataArray.length;
93    this.notifyDataAdd(this.dataArray.length - 1);
94  }
95
96  public deleteData(index: number): void {
97    this.dataArray.splice(index, 1);
98    this.dataCount = this.dataArray.length;
99    this.notifyDataDelete(index);
100  }
101}
102
103export class FilesData {
104  public id: string;
105  public uri: string;
106  public thumbUri: string;
107  public displayName: string;
108  public deviceId: string;
109  public flags: number;
110  public name: string;
111  public fileName: string;
112  public mode: string;
113  public size: number;
114  public mtime: number;
115  public suffix: string;
116  public mimeType: string;
117  public icon: any;
118  public gridIcon: any;
119  public localGridIcon: any;
120  public isChecked: boolean;
121  public path?: string;
122  public sub?: number;
123  public scale?: number;
124  public angle?: number;
125  public offsetX?: number | string;
126  public offsetY?: number | string;
127  public picWidth?: number | string;
128  public picHeight?: number | string;
129  public fileIterator?: fileAccess.FileInfo;
130  public isMedia: boolean = false;
131  public isImage: boolean = false;
132  public isVideo: boolean = false;
133  public isAudio: boolean = false;
134  public isFolder: boolean = false;
135  public duration: number;
136  public mimeTypeObj: MimeType;
137  public subFolderList: FilesData[];
138  public subFileList: FilesData[];
139  public layer: number;
140  public autoShow: boolean = false;
141  public currentDir?: string;
142
143  constructor(obj) {
144    this.isFolder = obj.isFolder || FileUtil.isFolder(obj.mode);
145    this.id = obj.id || randomId();
146    this.uri = obj.uri || '';
147    this.deviceId = obj.deviceId || '';
148    this.flags = obj.flags || 0;
149    this.name = obj.name || '';
150    this.fileName = obj.fileName || obj.displayName || '';
151    this.suffix = formatSuffix(this.fileName);
152    this.mode = obj.mode || '';
153    this.size = obj.size || 0;
154    this.mtime = obj.mtime * MILLISECOND.ONE_SECOND || 0;
155    this.mimeType = obj.mimeType || '';
156    this.isChecked = false;
157    this.path = obj.path || obj.relativePath || '';
158    this.sub = obj.sub || 0;
159    this.scale = obj.scale || 1;
160    this.angle = obj.angle || 0;
161    this.offsetX = obj.offsetX || 0;
162    this.offsetY = obj.offsetY || 0;
163    this.picWidth = obj.picWidth || '100%';
164    this.picHeight = obj.picHeight || '100%';
165    this.fileIterator = obj.fileIterator;
166    this.duration = obj.duration || 0;
167    this.mimeTypeObj = getFileIcon(this.fileName, this.isFolder);
168    this.icon = this.mimeTypeObj.getResID();
169    this.gridIcon = this.mimeTypeObj.getGridResID();
170    this.localGridIcon = this.mimeTypeObj.getLocalGridResID();
171    if (this.mimeTypeObj.isMedia()) {
172      this.thumbUri = this.uri;
173    }
174    if (this.isFolder) {
175      this.sub = getSubFileNum(this.fileIterator);
176    }
177    this.currentDir = FileUtil.getCurrentDir(this.path, this.isFolder);
178  }
179
180  setFileName(fileName: string): void {
181    this.fileName = fileName;
182    this.mimeTypeObj = getFileIcon(this.fileName);
183    this.icon = this.mimeTypeObj.getResID();
184    this.gridIcon = this.mimeTypeObj.getGridResID();
185    this.localGridIcon = this.mimeTypeObj.getLocalGridResID();
186    if (this.mimeTypeObj.isMedia()) {
187      this.thumbUri = `${this.uri}/thumbnail/${THUMBNAIL_SIZE.WIDTH}/${THUMBNAIL_SIZE.HEIGHT}`;
188    }
189  }
190
191  pickFile(startModeOptions: StartModeOptions): void {
192    AbilityCommonUtil.terminateFilePicker([this.uri], ResultCodePicker.SUCCESS, startModeOptions);
193  }
194
195  setSubFolderList(subFolderList: FilesData[]) {
196    this.subFolderList = subFolderList;
197  }
198
199  setSubList(subList: FilesData[]) {
200    if (!ArrayUtil.isEmpty(subList)) {
201      let folderList: FilesData[] =[];
202      let fileList: FilesData[] = [];
203      for (let i = 0; i < subList.length; i++) {
204        let fileData: FilesData = subList[i];
205        if (fileData.isFolder) {
206          folderList.push(fileData);
207        } else {
208          fileList.push(fileData);
209        }
210      }
211      this.subFolderList = folderList;
212      this.subFileList = fileList;
213    }
214  }
215
216  hasSubFolderList(): boolean {
217    if (ArrayUtil.isEmpty(this.subFolderList)) {
218      return false;
219    }
220    return this.subFolderList.length > 0;
221  }
222
223  getSubFolderList(): FilesData[] {
224    return this.subFolderList;
225  }
226
227  setLayer(layer: number) {
228    this.layer = layer;
229  }
230
231  getLayer(): number {
232    if (this.layer) {
233      return this.layer;
234    }
235    return 1;
236  }
237}
238
239export function getSubFileNum(fileInfo: fileAccess.FileInfo): number {
240  let subFileNum = 0;
241  if (!fileInfo) {
242    return subFileNum;
243  }
244  let fileIterator = fileInfo.listFile();
245  if (!fileIterator) {
246    return subFileNum;
247  }
248  let result = fileIterator.next();
249  let isDone = result.done;
250  while (!isDone) {
251    subFileNum += 1;
252    result = fileIterator.next();
253    isDone = result.done;
254  }
255  return subFileNum;
256}
257
258export class SelectedFileData {
259  public id?: string;
260  public uri: string;
261  public mimeType: string;
262  public thumbUri: string;
263  public title: string;
264  public fileName: string;
265  public mode: string;
266  public relativePath: string;
267  public size: number;
268  public albumUri: string;
269  public albumName: string;
270  public isFolder: boolean;
271  public displayName?: string;
272
273  constructor(obj) {
274    this.id = obj.id || -1;
275    this.uri = obj.uri || '';
276    this.mimeType = obj.mimetype || '';
277    this.thumbUri = obj.thumbUri || '';
278    this.title = obj.title || '';
279    this.fileName = obj.fileName || obj.displayName || '';
280    this.mode = obj.mode || '';
281    this.isFolder = obj.isFolder;
282    this.relativePath = obj.relativePath || '';
283    this.size = obj.size || 0;
284    this.albumUri = obj.albumUri || '';
285    this.albumName = obj.albumName || '';
286  }
287}
288
289export class FileData {
290  public id: string;
291  public fileName: string;
292  public thumbnail: string;
293  public editedTime: string;
294  public subItemSize: number;
295  public parentFolder: string;
296  public fileType: string;
297  public fileSize: number;
298  public isChecked: boolean;
299  public children: [];
300
301  constructor(id: string, fileName: string, thumbnail: string, editedTime: string, subItemSize: number,
302              parentFolder: string, fileType: string, fileSize: number, isChecked: boolean, children: []) {
303    this.id = id;
304    this.fileName = fileName;
305    this.thumbnail = thumbnail;
306    this.editedTime = editedTime;
307    this.subItemSize = subItemSize;
308    this.parentFolder = parentFolder;
309    this.fileType = fileType;
310    this.fileSize = fileSize;
311    this.isChecked = isChecked;
312    this.children = children;
313  }
314}
315
316export class FileDetail {
317  public key: string | Resource;
318  public value: string | Resource;
319  public path?: string = '';
320  public params?: any;
321
322  constructor(key: string, value: string, path: string, params: any) {
323    this.key = key;
324    this.value = value;
325    this.path = path;
326    this.params = params;
327  }
328}
329
330export class BottomOptions {
331  public optionName: string;
332  public name: string;
333  public icon: Resource;
334  public disabled: boolean = false;
335  public display: boolean = true;
336
337  constructor(optionName: string, name: string, icon: Resource, disabled: boolean, display: boolean) {
338    this.optionName = optionName;
339    this.name = name;
340    this.icon = icon;
341    this.disabled = disabled;
342    this.display = display;
343  }
344}