• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 = {} as Resource;
31  mediaType: mediaLibrary.MediaType = mediaLibrary.MediaType.FILE
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          .id('back')
65          .width(36)
66          .height(36)
67          .objectFit(ImageFit.Fill)
68          .alignSelf(ItemAlign.Start)
69          .responseRegion({
70            x: 0,
71            y: 0,
72            width: 45,
73            height: 45
74          })
75          .stateStyles({
76            pressed: this.imagePressedStyles
77          })
78          .onClick(() => {
79            router.back()
80          })
81
82        Text(this.title)
83          .fontSize(24)
84          .margin({ left: 10 })
85          .fontWeight(FontWeight.Bold)
86          .fontColor($r('app.color.black'))
87
88        Blank()
89
90        if (this.mediaType === mediaLibrary.MediaType.FILE) {
91          Image($r('app.media.add'))
92            .id('fileAdd')
93            .width(36)
94            .height(36)
95            .objectFit(ImageFit.Fill)
96            .alignSelf(ItemAlign.End)
97            .responseRegion({
98              x: 0,
99              y: 0,
100              width: 45,
101              height: 45
102            })
103            .stateStyles({
104              pressed: this.imagePressedStyles
105            })
106            .onClick(async () => {
107              let fileAsset: mediaLibrary.FileAsset = await FileManager.createTxtFileAsset(getContext(this))
108              if (fileAsset == undefined) {
109                Logger.error("createTxtFileAsset undefined")
110                return
111              }
112              this.fileList.pushData(fileAsset)
113              this.isNoFile = false
114            })
115        }
116      }
117      .width('100%')
118      .margin({ top: 10, bottom: 20 })
119
120      if (this.isNoFile) {
121        Column() {
122          Image($r('app.media.no_file'))
123            .id('no_file')
124            .width(36)
125            .height(36)
126            .margin({ top: 50 })
127            .objectFit(ImageFit.Fill)
128
129          Text($r('app.string.no_file'))
130            .fontSize(16)
131            .margin({ top: 10 })
132            .fontWeight(FontWeight.Bold)
133            .fontColor($r('app.color.font_gray'))
134        }
135        .width('100%')
136      } else {
137        List() {
138          LazyForEach(this.fileList, (listItem: mediaLibrary.FileAsset) => {
139            ListItem() {
140              FileListItemComponent({
141                itemFileList: $fileList,
142                fileListItem: listItem,
143                itemClickFunction: this.itemClickFunction,
144                itemId: listItem.id,
145                itemShowDeleteButton: $showDeleteButton,
146                itemIsNoFile: $isNoFile
147              })
148            }
149          }, (listItem: mediaLibrary.FileAsset) => JSON.stringify(listItem.title))
150        }
151        .height('100%')
152        .width('100%')
153      }
154    }
155    .height('100%')
156    .width('100%')
157    .backgroundColor($r('app.color.white'))
158    .padding(20)
159  }
160}
161
162@Component
163struct FileListItemComponent {
164  @Link itemFileList: FileDataSource
165  @Link itemShowDeleteButton: boolean
166  @Link itemIsNoFile: boolean
167  private fileListItem: mediaLibrary.FileAsset = {} as mediaLibrary.FileAsset;
168  private itemClickFunction: (fileAsset: mediaLibrary.FileAsset) => void = () => {}
169  private itemId: number = 0
170
171  @Styles itemPressedStyles() {
172    .backgroundColor($r('app.color.item_pressed'))
173    .borderRadius(10)
174  }
175
176  build() {
177    Column() {
178      Row() {
179        ThumbnailImage({ fileAsset: this.fileListItem })
180          .width(40)
181          .height(40)
182          .margin({ left: 20 })
183
184        Column() {
185          Text(this.fileListItem.title)
186            .maxLines(1)
187            .width('75%')
188            .textOverflow({overflow:TextOverflow.Ellipsis})
189            .fontSize(16)
190            .fontColor($r('app.color.black'))
191
192          Text(new Date(this.fileListItem.dateAdded * ONE_SECOND).toLocaleDateString() + ' - ' +
193          Math.ceil(this.fileListItem.size / SIZE_M) + 'M')
194            .fontSize(12)
195            .margin({ top: 5 })
196            .fontColor($r('app.color.font_gray'))
197        }
198        .margin({ left: 10 })
199        .alignItems(HorizontalAlign.Start)
200
201        Blank()
202
203        if (this.itemShowDeleteButton) {
204          Image($r('app.media.delete'))
205            .id('fileListDelete')
206            .width(30)
207            .height(30)
208            .margin({ right: 20 })
209            .objectFit(ImageFit.Fill)
210            .responseRegion({
211              x: 0,
212              y: 0,
213              width: 50,
214              height: 50
215            })
216            .stateStyles({
217              pressed: this.itemPressedStyles
218            })
219            .onClick(() => {
220              FileManager.deleteFileAsset(this.fileListItem)
221              this.itemFileList.deleteData(this.itemId)
222              this.itemShowDeleteButton = false
223              if (this.itemFileList.totalCount() === 0) {
224                this.itemIsNoFile = true
225              }
226            })
227        }
228      }
229      .height(56)
230      .width('100%')
231      .margin({ top: 10 })
232    }
233    .width('100%')
234    .stateStyles({
235      pressed: this.itemPressedStyles
236    })
237    .onClick(async () => {
238      this.itemClickFunction(this.fileListItem)
239    })
240    .gesture(LongPressGesture({ repeat: true })
241      .onAction((event?: GestureEvent) => {
242        this.itemShowDeleteButton = true
243      })
244    )
245  }
246}