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