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 */ 15 16import router from '@ohos.router' 17import mediaLibrary from '@ohos.multimedia.mediaLibrary' 18import { Logger, FileManager, ThumbnailImage } from '@ohos/feature-file-manager' 19import FileDataSource from '../../data/FileDataSource' 20 21const SIZE_M: number = 1024 * 1024 22const ONE_SECOND: number = 1000 23 24@Preview 25@Component 26export struct FileList { 27 @State fileList: FileDataSource = new FileDataSource() 28 @State isNoFile: boolean = true 29 @State showDeleteButton: boolean = false 30 title: Resource 31 mediaType: mediaLibrary.MediaType 32 itemClickFunction: (fileAsset: mediaLibrary.FileAsset) => void 33 34 async aboutToAppear() { 35 let files = await FileManager.getFileAssets(getContext(), this.mediaType) 36 if (files == undefined) { 37 Logger.error('files undefined') 38 return 39 } 40 if (files.getCount() > 0) { 41 Logger.debug('show list') 42 this.isNoFile = false 43 } 44 for (let i = 0; i < files.getCount(); i++) { 45 let fileAsset: mediaLibrary.FileAsset = await files.getNextObject() 46 if (fileAsset == undefined) { 47 continue 48 } 49 Logger.debug('getFileAssetsByType success, fileAsset.displayName ' + i + ': ' + fileAsset.displayName + 50 ' data:' + fileAsset.dateAdded, +', ' + fileAsset.dateModified) 51 this.fileList.pushData(fileAsset) 52 } 53 } 54 55 @Styles imagePressedStyles() { 56 .backgroundColor($r('app.color.item_pressed')) 57 .borderRadius(10) 58 } 59 60 build() { 61 Column() { 62 Row() { 63 Image($r('app.media.back')) 64 .width(36) 65 .height(36) 66 .objectFit(ImageFit.Fill) 67 .alignSelf(ItemAlign.Start) 68 .responseRegion({ 69 x: 0, 70 y: 0, 71 width: 45, 72 height: 45 73 }) 74 .stateStyles({ 75 pressed: this.imagePressedStyles 76 }) 77 .onClick(() => { 78 router.back() 79 }) 80 81 Text(this.title) 82 .fontSize(24) 83 .margin({ left: 10 }) 84 .fontWeight(FontWeight.Bold) 85 .fontColor($r('app.color.black')) 86 87 Blank() 88 89 if (this.mediaType === mediaLibrary.MediaType.FILE) { 90 Image($r('app.media.add')) 91 .width(36) 92 .height(36) 93 .objectFit(ImageFit.Fill) 94 .alignSelf(ItemAlign.End) 95 .responseRegion({ 96 x: 0, 97 y: 0, 98 width: 45, 99 height: 45 100 }) 101 .stateStyles({ 102 pressed: this.imagePressedStyles 103 }) 104 .onClick(async () => { 105 let fileAsset: mediaLibrary.FileAsset = await FileManager.createTxtFileAsset(getContext(this)) 106 if (fileAsset == undefined) { 107 Logger.error("createTxtFileAsset undefined") 108 return 109 } 110 this.fileList.pushData(fileAsset) 111 this.isNoFile = false 112 }) 113 } 114 } 115 .width('100%') 116 .margin({ top: 10, bottom: 20 }) 117 118 if (this.isNoFile) { 119 Column() { 120 Image($r('app.media.no_file')) 121 .width(36) 122 .height(36) 123 .margin({ top: 50 }) 124 .objectFit(ImageFit.Fill) 125 126 Text($r('app.string.no_file')) 127 .fontSize(16) 128 .margin({ top: 10 }) 129 .fontWeight(FontWeight.Bold) 130 .fontColor($r('app.color.font_gray')) 131 } 132 .width('100%') 133 } else { 134 List() { 135 LazyForEach(this.fileList, (listItem: mediaLibrary.FileAsset) => { 136 ListItem() { 137 FileListItemComponent({ 138 itemFileList: $fileList, 139 fileListItem: listItem, 140 itemClickFunction: this.itemClickFunction, 141 itemId: listItem.id, 142 itemShowDeleteButton: $showDeleteButton, 143 itemIsNoFile: $isNoFile 144 }) 145 } 146 }, (listItem, index) => { 147 return JSON.stringify(listItem) + index 148 }) 149 } 150 .height('100%') 151 .width('100%') 152 } 153 } 154 .height('100%') 155 .width('100%') 156 .backgroundColor($r('app.color.white')) 157 .padding(20) 158 } 159} 160 161@Component 162struct FileListItemComponent { 163 @Link itemFileList: FileDataSource 164 @Link itemShowDeleteButton: boolean 165 @Link itemIsNoFile: boolean 166 private fileListItem: mediaLibrary.FileAsset 167 private itemClickFunction: (fileAsset: mediaLibrary.FileAsset) => void 168 private itemId: number 169 170 @Styles itemPressedStyles() { 171 .backgroundColor($r('app.color.item_pressed')) 172 .borderRadius(10) 173 } 174 175 build() { 176 Column() { 177 Row() { 178 ThumbnailImage({ fileAsset: this.fileListItem }) 179 .width(40) 180 .height(40) 181 .margin({ left: 20 }) 182 183 Column() { 184 Text(this.fileListItem.title) 185 .fontSize(16) 186 .fontColor($r('app.color.black')) 187 188 Text(new Date(this.fileListItem.dateAdded * ONE_SECOND).toLocaleDateString() + ' - ' + 189 Math.ceil(this.fileListItem.size / SIZE_M) + 'M') 190 .fontSize(12) 191 .margin({ top: 5 }) 192 .fontColor($r('app.color.font_gray')) 193 } 194 .margin({ left: 10 }) 195 .alignItems(HorizontalAlign.Start) 196 197 Blank() 198 199 if (this.itemShowDeleteButton) { 200 Image($r('app.media.delete')) 201 .width(30) 202 .height(30) 203 .margin({ right: 20 }) 204 .objectFit(ImageFit.Fill) 205 .responseRegion({ 206 x: 0, 207 y: 0, 208 width: 50, 209 height: 50 210 }) 211 .stateStyles({ 212 pressed: this.itemPressedStyles 213 }) 214 .onClick(() => { 215 FileManager.deleteFileAsset(getContext(this), this.fileListItem) 216 this.itemFileList.deleteData(this.itemId) 217 this.itemShowDeleteButton = false 218 if (this.itemFileList.totalCount() === 0) { 219 this.itemIsNoFile = true 220 } 221 }) 222 } 223 } 224 .height(56) 225 .width('100%') 226 .margin({ top: 10 }) 227 } 228 .width('100%') 229 .stateStyles({ 230 pressed: this.itemPressedStyles 231 }) 232 .onClick(async () => { 233 this.itemClickFunction(this.fileListItem) 234 }) 235 .gesture(LongPressGesture({ repeat: true }) 236 .onAction((event: GestureEvent) => { 237 this.itemShowDeleteButton = true 238 }) 239 ) 240 } 241}