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 { Log } from '@ohos/base/src/main/ets/utils/Log'; 16import { LazyItem, ItemDataSource } from '@ohos/base/src/main/ets/vm/ItemDataSource'; 17import { MediaDataItem } from '@ohos/base/src/main/ets/data/MediaDataItem'; 18import { TimelineDataImpl } from '../model/TimelineDataImpl'; 19import { TimelineDataItem } from '../data/TimelineDataItem'; 20 21const TAG = "TimelineItemDataSource" 22 23export class TimelineItemDataSource extends ItemDataSource { 24 groupItem: TimelineDataItem[] = []; 25 private timelineDataImpl: TimelineDataImpl = new TimelineDataImpl(); 26 27 constructor() { 28 super() 29 } 30 31 totalCount(): number { 32 let count = 0 33 this.groupItem.forEach((item: TimelineDataItem) => { 34 count += 1 + item.groupChild.length; 35 }) 36 return count; 37 } 38 39 childCount(): number { 40 let count = 0; 41 this.groupItem.forEach((item: TimelineDataItem) => { 42 count += item.groupChild.length; 43 }) 44 return count; 45 } 46 47 getIndexByChildIndex(childIndex: number): number { 48 let index = 0; 49 for (let i = 0;i < this.groupItem.length; i++) { 50 let childCount = this.groupItem[i].groupChild.length 51 if (childIndex >= childCount) { 52 index += (1 + childCount); 53 childIndex -= childCount; 54 } else { 55 index += (1 + childIndex); 56 break; 57 } 58 } 59 return index; 60 } 61 62 getIndexByItem(item: MediaDataItem): number { 63 let index = 0; 64 let length = this.groupItem.length; 65 for (let i = 0;i < length; i++) { 66 let childLength = this.groupItem[i].groupChild.length; 67 let endDate = this.groupItem[i].groupChild[childLength-1].dateAdded // the min of the group 68 if (item.dateAdded < endDate) { 69 index += (1 + childLength); 70 continue; 71 } 72 let childIndex: number = this.groupItem[i].groupChild.indexOf(item); 73 if (childIndex < 0) { 74 index = -1; 75 } else { 76 index += (1 + childIndex); 77 } 78 break; 79 } 80 return index 81 } 82 83 getDataByIndex(index: number): TimelineDataItem | MediaDataItem { 84 let item: TimelineDataItem | MediaDataItem = undefined; 85 let count = 0; 86 for (let i = 0;i < this.groupItem.length; i++) { 87 let groupItem: TimelineDataItem = this.groupItem[i] 88 let childLength = groupItem.groupChild.length; 89 if (index == 0) { 90 item = groupItem; 91 break; 92 } else if (index <= childLength) { 93 item = groupItem.groupChild[index-1]; 94 item.index = count + index - 1; 95 break; 96 } else { 97 index -= (1 + childLength); 98 count += childLength; 99 } 100 } 101 return item; 102 } 103 104 getData(index: number): LazyItem<TimelineDataItem> | LazyItem<MediaDataItem> { 105 let item: LazyItem<TimelineDataItem> | LazyItem<MediaDataItem> = undefined; 106 let count = 0; 107 let lazyIndex = index; 108 for (let i = 0;i < this.groupItem.length; i++) { 109 let groupItem: TimelineDataItem = this.groupItem[i] 110 let childLength = groupItem.groupChild.length; 111 if (index == 0) { 112 item = new LazyItem<TimelineDataItem>(groupItem, lazyIndex, this.onTimelineDataUpdate.bind(this)); 113 break; 114 } else if (index <= childLength) { 115 item = new LazyItem<MediaDataItem>(groupItem.groupChild[index-1], lazyIndex, this.onMediaDataUpdate.bind(this)); 116 groupItem.groupChild[index-1].index = count + index - 1; 117 break; 118 } else { 119 index -= (1 + childLength); 120 count += childLength; 121 } 122 } 123 return item; 124 } 125 126 async reloadTimelineItemData(): Promise<boolean> { 127 Log.info(TAG, "reloadTimelineItemData"); 128 this.groupItem = await this.timelineDataImpl.getTimelineItemData(); 129 Log.debug(TAG, "reloadTimelineItemData finish"); 130 return this.groupItem.length == 0; 131 } 132 133 isSelect(): boolean { 134 let status = true; 135 for (let i = 0; i < this.groupItem.length; i++) { 136 if (!this.groupItem[i].isSelect()) { 137 status = false; 138 break; 139 } 140 } 141 return status; 142 } 143 144 setSelect(isSelect: boolean) { 145 this.groupItem.forEach((child: TimelineDataItem) => { 146 child.setSelect(isSelect); 147 }) 148 Log.info(TAG, "setSelect"); 149 this.notifyDataReload(); 150 } 151 152 getSelectedCount(): number { 153 let count = 0; 154 this.groupItem.forEach((child: TimelineDataItem) => { 155 count += child.getSelectedCount(); 156 }) 157 return count; 158 } 159 160 getItems(): MediaDataItem[] { 161 let items: MediaDataItem[] = []; 162 this.groupItem.forEach((group: TimelineDataItem) => { 163 group.groupChild.forEach((child: MediaDataItem) => { 164 items.push(child); 165 }) 166 }) 167 return items; 168 } 169 170 getSelectedItems(): MediaDataItem[] { 171 let items: MediaDataItem[] = []; 172 this.groupItem.forEach((group: TimelineDataItem) => { 173 group.groupChild.forEach((child: MediaDataItem) => { 174 if (child.isSelect) { 175 items.push(child); 176 } 177 }) 178 }) 179 return items; 180 } 181 182 getSelectedUris(): string[] { 183 let uris: string[] = []; 184 this.groupItem.forEach((group: TimelineDataItem) => { 185 group.groupChild.forEach((child: MediaDataItem) => { 186 if (child.isSelect) { 187 uris.push(child.uri); 188 } 189 }) 190 }) 191 return uris; 192 } 193 194 onTimelineDataUpdate(index: number, item: TimelineDataItem): void { 195 this.notifyDataChange(index); 196 Log.info(TAG, `onTimelineDataUpdate ${index}`); 197 for (let i = 0; i < item.groupChild.length; i++) { 198 this.notifyDataChange(index + 1 + i); 199 } 200 } 201 202 getIndexByMediaIndex(index:number) : number{ 203 let TimeLineTitleIndex = 0; 204 for (let i = 0;i < this.groupItem.length; i++) { 205 let groupItem: TimelineDataItem = this.groupItem[i] 206 let childLength = groupItem.groupChild.length; 207 if (index == 0) { 208 break; 209 } else if (index <= childLength) { 210 break; 211 } else { 212 index -= (1 + childLength); 213 TimeLineTitleIndex += childLength + 1; 214 } 215 } 216 return TimeLineTitleIndex; 217 } 218 219 onMediaDataUpdate(index: number, item: MediaDataItem): void { 220 Log.info(TAG, `onMediaDataUpdate ${index}`); 221 this.notifyDataChange(index); 222 this.notifyDataChange(this.getIndexByMediaIndex(index)); 223 } 224 225 dataReload(): void { 226 this.reloadTimelineItemData().then((isEmpty: boolean) => { 227 this.notifyDataReload(); 228 }) 229 } 230 231 dataRemove(): void { 232 let count: number = this.totalCount(); 233 for (let i = this.groupItem.length - 1;i >= 0; i--) { 234 count -= (this.groupItem[i].groupChild.length + 1); 235 let removeList: number[] = this.groupItem[i].dataRemove(); 236 removeList.forEach((index: number) => { 237 super.notifyDataDelete(count + 1 + index); 238 }) 239 if (this.groupItem[i].groupChild.length == 0) { 240 this.groupItem.splice(i, 1); 241 super.notifyDataDelete(count); 242 } 243 } 244 } 245}