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 */ 15import MediaLib from '@ohos.multimedia.mediaLibrary'; 16import { Log } from '../utils/Log'; 17import { WindowConstants } from '../constants/WindowConstants'; 18import mediaModel from '../model/MediaModel'; 19import screenManager from '../manager/ScreenManager'; 20import { MediaConstants } from '../constants/MediaConstants'; 21import { getFetchOptions } from '../helper/MediaDataHelper'; 22import { MediaDataItem } from '../data/MediaDataItem'; 23import { FavorMediaDataItem } from '../data/FavorMediaDataItem'; 24import { TrashMediaDataItem } from '../data/TrashMediaDataItem'; 25import mediaDataItemCache from '../data/MediaDataItemCache'; 26import trashMediaDataItemCache from '../data/TrashMediaDataItemCache'; 27 28 29const TAG = "GroupDataImpl" 30 31export class GroupDataImpl { 32 private selectType: number = MediaConstants.SELECT_TYPE_ALL; 33 private albumId: string = ""; 34 private deviceId: string = ""; 35 36 setSelectType(selectType: number) { 37 this.selectType = selectType; 38 } 39 40 setAlbumId(id: string) { 41 Log.info(TAG, `setAlbumId: ${id}`); 42 this.albumId = id; 43 } 44 45 setDeviceId(id: string) { 46 Log.info(TAG, `setDeviceId: ${id}`); 47 this.deviceId = id; 48 } 49 50 async reloadGroupItemData(isGrid: boolean): Promise<MediaDataItem[]> { 51 if (isGrid) { 52 return this.reloadGridGroupItemData(); 53 } else { 54 return this.reloadBrowserGroupItemData(); 55 } 56 } 57 58 async reloadBrowserGroupItemData(): Promise<MediaDataItem[]> { 59 Log.debug(TAG, `reloadBrowserGroupItemData`); 60 let groupDataItem = []; 61 let fetchOption = await getFetchOptions(this.selectType, this.albumId, this.deviceId); 62 if (fetchOption == undefined) { 63 return []; 64 } 65 let count: number = 0; 66 let groupCount: number = this.getCount(); 67 let mediaFileAssets = await this.getMediaItemFileAssets(fetchOption, 0, groupCount); 68 if (this.albumId == MediaConstants.ALBUM_ID_FAVOR) { 69 count = (await mediaModel.getAllFavorMediaItem(fetchOption, true)).counts; 70 for (let i = 0;i < count; i++) { 71 let favorMediaItem = new FavorMediaDataItem(fetchOption.selections, fetchOption.selectionArgs, i); 72 if (i < mediaFileAssets.length) { 73 if (mediaDataItemCache.hasKey(mediaFileAssets[i].uri)) { 74 favorMediaItem.favouriteStatus = mediaDataItemCache.get(mediaFileAssets[i].uri).favouriteStatus; 75 favorMediaItem.orientation = mediaDataItemCache.get(mediaFileAssets[i].uri).orientation; 76 } 77 favorMediaItem.update(mediaFileAssets[i]); 78 } 79 groupDataItem.push(favorMediaItem); 80 } 81 } else if (this.albumId == MediaConstants.ALBUM_ID_RECYCLE) { 82 count = (await mediaModel.getAllTrashMediaItem(fetchOption, true)).counts; 83 for (let i = 0;i < count; i++) { 84 let trashMediaItem = new TrashMediaDataItem(fetchOption.selections, fetchOption.selectionArgs, i); 85 if (i < mediaFileAssets.length) { 86 if (mediaDataItemCache.hasKey(mediaFileAssets[i].uri)) { 87 trashMediaItem.favouriteStatus = mediaDataItemCache.get(mediaFileAssets[i].uri).favouriteStatus; 88 trashMediaItem.orientation = mediaDataItemCache.get(mediaFileAssets[i].uri).orientation; 89 } 90 trashMediaItem.update(mediaFileAssets[i]); 91 } 92 groupDataItem.push(trashMediaItem); 93 } 94 } else { 95 count = (await mediaModel.getAllCommonMediaItem(fetchOption, true)).counts; 96 for (let i = 0;i < count; i++) { 97 let mediaItem: MediaDataItem = new MediaDataItem(fetchOption.selections, fetchOption.selectionArgs, this.deviceId, i); 98 if (i < mediaFileAssets.length) { 99 if (mediaDataItemCache.hasKey(mediaFileAssets[i].uri)) { 100 mediaItem = mediaDataItemCache.get(mediaFileAssets[i].uri); 101 } else { 102 mediaDataItemCache.set(mediaFileAssets[i].uri, mediaItem); 103 } 104 mediaItem.update(mediaFileAssets[i]); 105 } 106 groupDataItem.push(mediaItem); 107 } 108 } 109 110 Log.debug(TAG, `reload finish count:${count}`); 111 return groupDataItem; 112 } 113 114 async reloadGridGroupItemData(): Promise<MediaDataItem[]> { 115 Log.debug(TAG, `reloadGridGroupItemData`); 116 let groupDataItem = []; 117 let fetchOption = await getFetchOptions(this.selectType, this.albumId, this.deviceId); 118 if (fetchOption == undefined) { 119 return []; 120 } 121 let groupCount: number = this.getCount(); 122 let mediaFileAssets = await this.getMediaItemFileAssets(fetchOption, 0, groupCount); 123 if (this.albumId == MediaConstants.ALBUM_ID_FAVOR) { 124 let count: number = (await mediaModel.getAllFavorMediaItem(fetchOption, true)).counts; 125 for (let i = 0;i < count; i++) { 126 let item = new FavorMediaDataItem(fetchOption.selections, fetchOption.selectionArgs, i); 127 if (i < mediaFileAssets.length) { 128 if (mediaDataItemCache.hasKey(mediaFileAssets[i].uri)) { 129 item = mediaDataItemCache.get(mediaFileAssets[i].uri); 130 } 131 else { 132 mediaDataItemCache.set(mediaFileAssets[i].uri, item); 133 } 134 item.update(mediaFileAssets[i]); 135 } 136 groupDataItem.push(item); 137 } 138 } else if (this.albumId == MediaConstants.ALBUM_ID_RECYCLE) { 139 let count: number = (await mediaModel.getAllTrashMediaItem(fetchOption, true)).counts; 140 for (let i = 0;i < count; i++) { 141 let item = new TrashMediaDataItem(fetchOption.selections, fetchOption.selectionArgs, i); 142 if (i < mediaFileAssets.length) { 143 if (trashMediaDataItemCache.hasKey(mediaFileAssets[i].uri)) { 144 item = trashMediaDataItemCache.get(mediaFileAssets[i].uri); 145 } 146 else 147 { 148 trashMediaDataItemCache.set(mediaFileAssets[i].uri, item); 149 } 150 item.update(mediaFileAssets[i]); 151 } 152 groupDataItem.push(item); 153 } 154 } else { 155 let count: number = (await mediaModel.getAllCommonMediaItem(fetchOption, true)).counts; 156 for (let i = 0;i < count; i++) { 157 let item = new MediaDataItem(fetchOption.selections, fetchOption.selectionArgs, this.deviceId, i); 158 if (i < mediaFileAssets.length) { 159 if (mediaDataItemCache.hasKey(mediaFileAssets[i].uri)) { 160 item = mediaDataItemCache.get(mediaFileAssets[i].uri); 161 } else { 162 mediaDataItemCache.set(mediaFileAssets[i].uri, item); 163 } 164 item.update(mediaFileAssets[i]); 165 } 166 groupDataItem.push(item); 167 } 168 } 169 // do not use await to avoid load cost too much time 170 this.loadReset(fetchOption, groupDataItem, groupCount); 171 172 Log.debug(TAG, `reload finish`); 173 return groupDataItem; 174 } 175 176 private async getMediaItemFileAssets(baseFetchOption: MediaLib.MediaFetchOptions, start: number, count: number): Promise<MediaLib.FileAsset[]> { 177 let fetchOption: MediaLib.MediaFetchOptions = { 178 selections: baseFetchOption.selections, 179 selectionArgs: baseFetchOption.selectionArgs, 180 order: `date_added DESC LIMIT ${start},${count}` 181 } 182 if (this.deviceId.length > 0) { 183 fetchOption['networkId'] = this.deviceId; 184 } 185 if (this.albumId == MediaConstants.ALBUM_ID_FAVOR) { 186 return await mediaModel.getAllFavorMediaItems(fetchOption); 187 } else if (this.albumId == MediaConstants.ALBUM_ID_RECYCLE) { 188 return await mediaModel.getAllTrashMediaItems(fetchOption); 189 } else { 190 return await mediaModel.getAllMediaItems(fetchOption); 191 } 192 } 193 194 private getCount(): number { 195 let contentWidth = screenManager.getWinWidth(); 196 let maxThumbWidth = px2vp(WindowConstants.GRID_IMAGE_SIZE) * WindowConstants.GRID_MAX_SIZE_RATIO; 197 let columns = Math.max(WindowConstants.GRID_MIN_COUNT, Math.ceil((contentWidth + WindowConstants.GRID_GUTTER) / (maxThumbWidth + WindowConstants.GRID_GUTTER))); 198 let contentHeight = screenManager.getWinHeight() - WindowConstants.ACTION_BAR_HEIGHT - screenManager.getNaviBarHeight(); 199 let rows = Math.ceil((contentHeight + WindowConstants.GRID_GUTTER) / (maxThumbWidth + WindowConstants.GRID_GUTTER)) + 4; 200 return columns * rows; 201 } 202 203 private async loadReset(fetchOption: MediaLib.MediaFetchOptions, items: MediaDataItem[], count) { 204 let itemLen = items.length; 205 let countLen = Math.ceil(itemLen / count); 206 for (let i = 1;i < countLen; i++) { 207 let mediaFileAsset: Array<MediaLib.FileAsset> = await this.getMediaItemFileAssets(fetchOption, i * count, count); 208 for (let j = 0;j < count; j++) { 209 if (i * count + j >= itemLen) { 210 return; 211 } 212 items[i * count+j].update(mediaFileAsset[j]); 213 } 214 } 215 } 216}