1bea4f105Sopenharmony_ci/* 2bea4f105Sopenharmony_ci * Copyright (c) 2021-2023 Huawei Device Co., Ltd. 3bea4f105Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4bea4f105Sopenharmony_ci * you may not use this file except in compliance with the License. 5bea4f105Sopenharmony_ci * You may obtain a copy of the License at 6bea4f105Sopenharmony_ci * 7bea4f105Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8bea4f105Sopenharmony_ci * 9bea4f105Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10bea4f105Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11bea4f105Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12bea4f105Sopenharmony_ci * See the License for the specific language governing permissions and 13bea4f105Sopenharmony_ci * limitations under the License. 14bea4f105Sopenharmony_ci */ 15bea4f105Sopenharmony_ci 16bea4f105Sopenharmony_ciimport { MILLISECOND } from '../../base/constants/Constant'; 17bea4f105Sopenharmony_ciimport { formatSuffix, getResourceString } from '../../base/utils/Tools'; 18bea4f105Sopenharmony_ciimport DateTimeUtil from '../../base/utils/DateTimeUtil'; 19bea4f105Sopenharmony_ciimport { FileMimeTypeUtil } from '../../base/utils/FileMimeTypeUtil'; 20bea4f105Sopenharmony_ciimport LanguageUtil from '../../base/utils/LanguageUtil'; 21bea4f105Sopenharmony_ciimport { MimeType } from './MimeType'; 22bea4f105Sopenharmony_ciimport { THUMBNAIL_SIZE } from '../../base/constants/UiConstant'; 23bea4f105Sopenharmony_ciimport { BasicDataSource } from './BasicDataSource'; 24bea4f105Sopenharmony_ciimport AbilityCommonUtil, { ResultCodePicker } from '../../base/utils/AbilityCommonUtil'; 25bea4f105Sopenharmony_ciimport { StartModeOptions } from '../../base/model/StartModeOptions'; 26bea4f105Sopenharmony_ciimport { photoAccessHelper } from '@kit.MediaLibraryKit'; 27bea4f105Sopenharmony_ciimport { dataSharePredicates } from '@kit.ArkData'; 28bea4f105Sopenharmony_ci 29bea4f105Sopenharmony_ciconst TAG = 'FileAssetModel'; 30bea4f105Sopenharmony_ci 31bea4f105Sopenharmony_ciexport class FileAssetLazyModel extends BasicDataSource { 32bea4f105Sopenharmony_ci private dataArray: FileAssetModel[] = []; 33bea4f105Sopenharmony_ci public dataCount: number = 0; 34bea4f105Sopenharmony_ci 35bea4f105Sopenharmony_ci public totalCount(): number { 36bea4f105Sopenharmony_ci return this.dataArray.length; 37bea4f105Sopenharmony_ci } 38bea4f105Sopenharmony_ci 39bea4f105Sopenharmony_ci public getDataArray(): FileAssetModel[] { 40bea4f105Sopenharmony_ci return this.dataArray; 41bea4f105Sopenharmony_ci } 42bea4f105Sopenharmony_ci 43bea4f105Sopenharmony_ci public setData(data: FileAssetModel[]): void { 44bea4f105Sopenharmony_ci this.dataArray = [...data]; 45bea4f105Sopenharmony_ci this.dataCount = this.dataArray.length; 46bea4f105Sopenharmony_ci this.notifyDataReload(); 47bea4f105Sopenharmony_ci } 48bea4f105Sopenharmony_ci 49bea4f105Sopenharmony_ci public getData(index: number): FileAssetModel { 50bea4f105Sopenharmony_ci return this.dataArray[index]; 51bea4f105Sopenharmony_ci } 52bea4f105Sopenharmony_ci 53bea4f105Sopenharmony_ci public selectAll(isSelected: boolean): void { 54bea4f105Sopenharmony_ci this.dataArray.forEach(item => { 55bea4f105Sopenharmony_ci item.isChecked = isSelected; 56bea4f105Sopenharmony_ci }); 57bea4f105Sopenharmony_ci } 58bea4f105Sopenharmony_ci 59bea4f105Sopenharmony_ci public getIndex(uri): number { 60bea4f105Sopenharmony_ci return this.dataArray.findIndex(item => item.uri === uri); 61bea4f105Sopenharmony_ci } 62bea4f105Sopenharmony_ci 63bea4f105Sopenharmony_ci public getSelectedFileList(): FileAssetModel[] { 64bea4f105Sopenharmony_ci return this.dataArray.filter(item => item.isChecked); 65bea4f105Sopenharmony_ci } 66bea4f105Sopenharmony_ci 67bea4f105Sopenharmony_ci public replaceData(index, data: FileAssetModel): void { 68bea4f105Sopenharmony_ci this.dataArray.splice(index, 1, data); 69bea4f105Sopenharmony_ci this.notifyDataChange(index); 70bea4f105Sopenharmony_ci } 71bea4f105Sopenharmony_ci 72bea4f105Sopenharmony_ci public addData(index: number, data: FileAssetModel): void { 73bea4f105Sopenharmony_ci this.dataArray.splice(index, 0, data); 74bea4f105Sopenharmony_ci this.dataCount = this.dataArray.length; 75bea4f105Sopenharmony_ci this.notifyDataAdd(index); 76bea4f105Sopenharmony_ci } 77bea4f105Sopenharmony_ci 78bea4f105Sopenharmony_ci public pushData(data: FileAssetModel): void { 79bea4f105Sopenharmony_ci this.dataArray.push(data); 80bea4f105Sopenharmony_ci this.dataCount = this.dataArray.length; 81bea4f105Sopenharmony_ci this.notifyDataAdd(this.dataArray.length - 1); 82bea4f105Sopenharmony_ci } 83bea4f105Sopenharmony_ci 84bea4f105Sopenharmony_ci public deleteData(index: number): void { 85bea4f105Sopenharmony_ci this.dataArray.splice(index, 1); 86bea4f105Sopenharmony_ci this.dataCount = this.dataArray.length; 87bea4f105Sopenharmony_ci this.notifyDataDelete(index); 88bea4f105Sopenharmony_ci } 89bea4f105Sopenharmony_ci} 90bea4f105Sopenharmony_ci 91bea4f105Sopenharmony_ci/** 92bea4f105Sopenharmony_ci * 媒体文件信息类 93bea4f105Sopenharmony_ci */ 94bea4f105Sopenharmony_ciexport class FileAssetModel { 95bea4f105Sopenharmony_ci public id: number; 96bea4f105Sopenharmony_ci public uri: string; 97bea4f105Sopenharmony_ci public mimeType: string; 98bea4f105Sopenharmony_ci public mediaType: number; 99bea4f105Sopenharmony_ci public displayName: string; 100bea4f105Sopenharmony_ci public title: string; 101bea4f105Sopenharmony_ci public relativePath: string; 102bea4f105Sopenharmony_ci public parent: number; 103bea4f105Sopenharmony_ci public size: number; 104bea4f105Sopenharmony_ci public dateAdded: number; 105bea4f105Sopenharmony_ci public dateModified: number; 106bea4f105Sopenharmony_ci public dateTaken: number; 107bea4f105Sopenharmony_ci public artist: string; 108bea4f105Sopenharmony_ci public audioAlbum: string; 109bea4f105Sopenharmony_ci public width: number; 110bea4f105Sopenharmony_ci public height: number; 111bea4f105Sopenharmony_ci public orientation: number; 112bea4f105Sopenharmony_ci public duration: number; 113bea4f105Sopenharmony_ci public albumId: number; 114bea4f105Sopenharmony_ci public albumUri: string; 115bea4f105Sopenharmony_ci public albumName: string; 116bea4f105Sopenharmony_ci // MediaLibrary.FileAsset对象外的属性 117bea4f105Sopenharmony_ci public fileName: string; 118bea4f105Sopenharmony_ci public fullPath: string; 119bea4f105Sopenharmony_ci public isChecked: boolean = false; 120bea4f105Sopenharmony_ci public suffix: string; 121bea4f105Sopenharmony_ci public icon: Resource | PixelMap; 122bea4f105Sopenharmony_ci public gridIcon: Resource | PixelMap; 123bea4f105Sopenharmony_ci public localGridIcon: Resource | PixelMap; 124bea4f105Sopenharmony_ci public lastModifiedDate: string | Resource; 125bea4f105Sopenharmony_ci public thumbUri: string; 126bea4f105Sopenharmony_ci public sortLabel: string = ''; 127bea4f105Sopenharmony_ci public mimeTypeObj: MimeType; 128bea4f105Sopenharmony_ci 129bea4f105Sopenharmony_ci constructor(file) { 130bea4f105Sopenharmony_ci this.id = file.id; 131bea4f105Sopenharmony_ci this.uri = file.uri; 132bea4f105Sopenharmony_ci this.mimeType = file.mimeType; 133bea4f105Sopenharmony_ci this.mediaType = file.mediaType; 134bea4f105Sopenharmony_ci this.displayName = file.displayName; 135bea4f105Sopenharmony_ci this.title = file.title; 136bea4f105Sopenharmony_ci this.relativePath = file.relativePath; 137bea4f105Sopenharmony_ci this.parent = file.parent; 138bea4f105Sopenharmony_ci this.size = file.size; 139bea4f105Sopenharmony_ci this.dateAdded = file.dateAdded; 140bea4f105Sopenharmony_ci this.dateModified = file.dateModified * MILLISECOND.ONE_SECOND; 141bea4f105Sopenharmony_ci this.dateTaken = file.dateTaken; 142bea4f105Sopenharmony_ci this.artist = file.artist; 143bea4f105Sopenharmony_ci this.audioAlbum = file.audioAlbum; 144bea4f105Sopenharmony_ci this.width = file.width; 145bea4f105Sopenharmony_ci this.height = file.height; 146bea4f105Sopenharmony_ci this.orientation = file.orientation; 147bea4f105Sopenharmony_ci this.duration = file.duration; 148bea4f105Sopenharmony_ci this.albumId = file.albumId; 149bea4f105Sopenharmony_ci this.albumUri = file.albumUri; 150bea4f105Sopenharmony_ci this.albumName = file.albumName; 151bea4f105Sopenharmony_ci 152bea4f105Sopenharmony_ci this.fileName = file.displayName; 153bea4f105Sopenharmony_ci this.mimeTypeObj = FileMimeTypeUtil.getFileMimeType(this.fileName); 154bea4f105Sopenharmony_ci this.fullPath = getFullPath(this); 155bea4f105Sopenharmony_ci this.suffix = formatSuffix(file.fileName); 156bea4f105Sopenharmony_ci this.icon = this.mimeTypeObj.getResID(); 157bea4f105Sopenharmony_ci this.gridIcon = this.mimeTypeObj.getGridResID(); 158bea4f105Sopenharmony_ci this.localGridIcon = this.mimeTypeObj.getLocalGridResID(); 159bea4f105Sopenharmony_ci this.lastModifiedDate = DateTimeUtil.getDateStringForCategory(this.dateModified); 160bea4f105Sopenharmony_ci this.sortLabel = file.sortLabel; 161bea4f105Sopenharmony_ci if (this.mimeTypeObj.isMedia()) { 162bea4f105Sopenharmony_ci this.thumbUri = `${this.uri}/thumbnail/${THUMBNAIL_SIZE.WIDTH}/${THUMBNAIL_SIZE.HEIGHT}`; 163bea4f105Sopenharmony_ci } 164bea4f105Sopenharmony_ci } 165bea4f105Sopenharmony_ci 166bea4f105Sopenharmony_ci setFileName(fileName: string): void { 167bea4f105Sopenharmony_ci this.fileName = fileName; 168bea4f105Sopenharmony_ci this.mimeTypeObj = FileMimeTypeUtil.getFileMimeType(this.fileName); 169bea4f105Sopenharmony_ci this.fullPath = getFullPath(this); 170bea4f105Sopenharmony_ci this.icon = this.mimeTypeObj.getResID(); 171bea4f105Sopenharmony_ci this.gridIcon = this.mimeTypeObj.getGridResID(); 172bea4f105Sopenharmony_ci this.localGridIcon = this.mimeTypeObj.getLocalGridResID(); 173bea4f105Sopenharmony_ci if (this.mimeTypeObj.isMedia()) { 174bea4f105Sopenharmony_ci this.thumbUri = `${this.uri}/thumbnail/${THUMBNAIL_SIZE.WIDTH}/${THUMBNAIL_SIZE.HEIGHT}`; 175bea4f105Sopenharmony_ci } 176bea4f105Sopenharmony_ci } 177bea4f105Sopenharmony_ci 178bea4f105Sopenharmony_ci pickFile(startModeOptions: StartModeOptions): void { 179bea4f105Sopenharmony_ci AbilityCommonUtil.terminateFilePicker([this.uri], ResultCodePicker.SUCCESS, startModeOptions); 180bea4f105Sopenharmony_ci } 181bea4f105Sopenharmony_ci} 182bea4f105Sopenharmony_ci 183bea4f105Sopenharmony_ci/** 184bea4f105Sopenharmony_ci * 对媒体文件进行排序 185bea4f105Sopenharmony_ci * @param dataList 待排序数组 186bea4f105Sopenharmony_ci * @param order 排序规则 187bea4f105Sopenharmony_ci * @param isDesc 是否倒序 188bea4f105Sopenharmony_ci * @return 排序后的数组 189bea4f105Sopenharmony_ci */ 190bea4f105Sopenharmony_cifunction sortFileAssetList(dataList) { 191bea4f105Sopenharmony_ci const language = LanguageUtil.getSystemLanguage(); 192bea4f105Sopenharmony_ci return dataList.sort((a, b) => { 193bea4f105Sopenharmony_ci if (b.dateModified !== a.dateModified) { 194bea4f105Sopenharmony_ci return b.dateModified - a.dateModified; 195bea4f105Sopenharmony_ci } else { 196bea4f105Sopenharmony_ci return b.displayName.localeCompare(a.displayName, language); 197bea4f105Sopenharmony_ci } 198bea4f105Sopenharmony_ci }) 199bea4f105Sopenharmony_ci} 200bea4f105Sopenharmony_ci 201bea4f105Sopenharmony_ci/** 202bea4f105Sopenharmony_ci * 媒体库查询条件类 203bea4f105Sopenharmony_ci */ 204bea4f105Sopenharmony_ciexport class MediaFetchOptions { 205bea4f105Sopenharmony_ci public selections: string = photoAccessHelper.PhotoKeys.PHOTO_TYPE + '=?'; 206bea4f105Sopenharmony_ci public selectionArgs: string[] = []; 207bea4f105Sopenharmony_ci public order: string = photoAccessHelper.PhotoKeys.DATE_MODIFIED + ' DESC'; 208bea4f105Sopenharmony_ci public uri: string = ''; 209bea4f105Sopenharmony_ci public networkId: string = ''; 210bea4f105Sopenharmony_ci public extendArgs: string = ''; 211bea4f105Sopenharmony_ci 212bea4f105Sopenharmony_ci constructor(mediaTypeArg: string = '') { 213bea4f105Sopenharmony_ci if (!mediaTypeArg) { 214bea4f105Sopenharmony_ci this.selections = ''; 215bea4f105Sopenharmony_ci } else { 216bea4f105Sopenharmony_ci this.selectionArgs.push(mediaTypeArg); 217bea4f105Sopenharmony_ci } 218bea4f105Sopenharmony_ci } 219bea4f105Sopenharmony_ci 220bea4f105Sopenharmony_ci /** 221bea4f105Sopenharmony_ci * 设置要查询文件的uri 222bea4f105Sopenharmony_ci */ 223bea4f105Sopenharmony_ci setUri(uri: string): void { 224bea4f105Sopenharmony_ci this.uri = uri; 225bea4f105Sopenharmony_ci } 226bea4f105Sopenharmony_ci 227bea4f105Sopenharmony_ci /** 228bea4f105Sopenharmony_ci * 追加其他查询条件 229bea4f105Sopenharmony_ci * @param selection 要查询的关键字 230bea4f105Sopenharmony_ci * @param selectionArg 要查询的值 231bea4f105Sopenharmony_ci */ 232bea4f105Sopenharmony_ci addSelection(selection: photoAccessHelper.PhotoKeys, selectionArg: string) { 233bea4f105Sopenharmony_ci if (this.selections.length) { 234bea4f105Sopenharmony_ci this.selections += ` AND ${selection} = ? `; 235bea4f105Sopenharmony_ci } else { 236bea4f105Sopenharmony_ci this.selections = `${selection} = ?`; 237bea4f105Sopenharmony_ci } 238bea4f105Sopenharmony_ci this.selectionArgs.push(selectionArg); 239bea4f105Sopenharmony_ci } 240bea4f105Sopenharmony_ci} 241bea4f105Sopenharmony_ci 242bea4f105Sopenharmony_ci/** 243bea4f105Sopenharmony_ci * 查询媒体库内指定类型的文件 244bea4f105Sopenharmony_ci * @param mediaFetchOptions 媒体库查询条件 245bea4f105Sopenharmony_ci * @return 文件列表 246bea4f105Sopenharmony_ci */ 247bea4f105Sopenharmony_ciexport async function getMediaFileDuration(mediaFetchOptions: MediaFetchOptions): Promise<number> { 248bea4f105Sopenharmony_ci const photoManageHelper: photoAccessHelper.PhotoAccessHelper = AbilityCommonUtil.getPhotoManageHelper(); 249bea4f105Sopenharmony_ci let predicates: dataSharePredicates.DataSharePredicates = new dataSharePredicates.DataSharePredicates(); 250bea4f105Sopenharmony_ci let fetchOptions: photoAccessHelper.FetchOptions = { 251bea4f105Sopenharmony_ci fetchColumns: mediaFetchOptions.selectionArgs, 252bea4f105Sopenharmony_ci predicates: predicates 253bea4f105Sopenharmony_ci }; 254bea4f105Sopenharmony_ci if (!photoManageHelper) { 255bea4f105Sopenharmony_ci return 0; 256bea4f105Sopenharmony_ci } 257bea4f105Sopenharmony_ci 258bea4f105Sopenharmony_ci let fetchResult: photoAccessHelper.FetchResult<photoAccessHelper.PhotoAsset> = 259bea4f105Sopenharmony_ci await photoManageHelper.getAssets(fetchOptions); 260bea4f105Sopenharmony_ci let photoAsset: photoAccessHelper.PhotoAsset = await fetchResult.getFirstObject(); 261bea4f105Sopenharmony_ci let duration: photoAccessHelper.MemberType = photoAsset.get(photoAccessHelper.PhotoKeys.DURATION); 262bea4f105Sopenharmony_ci return Number(duration) ?? 0; 263bea4f105Sopenharmony_ci} 264bea4f105Sopenharmony_ci 265bea4f105Sopenharmony_ciexport function getDurationByUri(mediaType: photoAccessHelper.PhotoType, uri: string): Promise<number> { 266bea4f105Sopenharmony_ci const option = new MediaFetchOptions(mediaType.toString()); 267bea4f105Sopenharmony_ci option.setUri(uri); 268bea4f105Sopenharmony_ci return getMediaFileDuration(option).then((res: number) => { 269bea4f105Sopenharmony_ci return res; 270bea4f105Sopenharmony_ci }).catch(() => { 271bea4f105Sopenharmony_ci return 0; 272bea4f105Sopenharmony_ci }) 273bea4f105Sopenharmony_ci} 274bea4f105Sopenharmony_ci 275bea4f105Sopenharmony_ci/** 276bea4f105Sopenharmony_ci * 根据文件名(后缀)判断媒体类型 277bea4f105Sopenharmony_ci * @param fileName 文件名 278bea4f105Sopenharmony_ci * @return 媒体类型photoAccessHelper.PhotoType 279bea4f105Sopenharmony_ci */ 280bea4f105Sopenharmony_ciexport function getMediaType(fileName: string): photoAccessHelper.PhotoType { 281bea4f105Sopenharmony_ci const mimeType = FileMimeTypeUtil.getFileMimeType(fileName); 282bea4f105Sopenharmony_ci if (mimeType.isImage()) { 283bea4f105Sopenharmony_ci return photoAccessHelper.PhotoType.IMAGE; 284bea4f105Sopenharmony_ci } else if (mimeType.isVideo()) { 285bea4f105Sopenharmony_ci return photoAccessHelper.PhotoType.VIDEO; 286bea4f105Sopenharmony_ci } else { 287bea4f105Sopenharmony_ci return 0; 288bea4f105Sopenharmony_ci } 289bea4f105Sopenharmony_ci} 290bea4f105Sopenharmony_ci 291bea4f105Sopenharmony_ci/** 292bea4f105Sopenharmony_ci * 获取文件的完整路径 293bea4f105Sopenharmony_ci * @param file 文件信息 294bea4f105Sopenharmony_ci * @return 完整路径 295bea4f105Sopenharmony_ci */ 296bea4f105Sopenharmony_ciexport function getFullPath(file: FileAssetModel): string { 297bea4f105Sopenharmony_ci return getResourceString($r('app.string.myPhone')) + '/' + file.relativePath + file.fileName; 298bea4f105Sopenharmony_ci} 299bea4f105Sopenharmony_ci 300bea4f105Sopenharmony_ci/** 301bea4f105Sopenharmony_ci * 设置文件列表排序后需要显示的label 302bea4f105Sopenharmony_ci * @param fileAssetList 文件列表 303bea4f105Sopenharmony_ci * @param order 排序规则 304bea4f105Sopenharmony_ci * @return 设置了label的文件数组 305bea4f105Sopenharmony_ci */ 306bea4f105Sopenharmony_ciexport function addSortLabel(fileAssetList): FileAssetModel[] { 307bea4f105Sopenharmony_ci fileAssetList.forEach((fileAsset: FileAssetModel) => { 308bea4f105Sopenharmony_ci fileAsset.sortLabel = DateTimeUtil.getDateStringForCategory(fileAsset.dateModified); 309bea4f105Sopenharmony_ci }); 310bea4f105Sopenharmony_ci return fileAssetList; 311bea4f105Sopenharmony_ci} 312bea4f105Sopenharmony_ci 313bea4f105Sopenharmony_ci 314