• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 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 promptAction from '@ohos.promptAction';
17import router from '@ohos.router';
18import { CustomDataSource } from '../components/CustomDataSource';
19import {
20  FileModel,
21  FileType,
22  fileUtils,
23  logger,
24  requestFiles,
25  requestDownload,
26  BackgroundTaskState,
27  TOAST_BOTTOM
28} from '@ohos/uploaddownload';
29import { SelectFolderDialog } from '../components/SelectFolderDialog';
30
31const TAG: string = 'Download';
32
33@Entry
34@Component
35struct Download {
36  private fileData: CustomDataSource = new CustomDataSource([]);
37  @StorageLink('isBackground') isBackground: boolean = false;
38  @StorageLink('backDownTaskState') backDownTaskState: BackgroundTaskState = BackgroundTaskState.NONE;
39  @Provide downloadFolder: Array<string> = [];
40  @State isGetData: boolean = false;
41  @State checkFile: Array<string> = [];
42  @State checkList: Array<boolean> = [];
43  @State isRunning: boolean = false;
44  @State isPause: boolean = false;
45  @State progress: number = 0;
46  private selectFolder = (folder: string) => {
47    logger.info(TAG, `selectFolder = ${folder}`);
48    this.download(folder);
49  }
50  private folderDialogController: CustomDialogController = new CustomDialogController({
51    builder: SelectFolderDialog({ selectFolder: this.selectFolder }),
52    autoCancel: true,
53    alignment: DialogAlignment.Bottom,
54    offset: { dx: 0, dy: -12 }
55  });
56
57  build() {
58    Navigation() {
59      Column() {
60        if (this.isGetData) {
61          LoadingProgress()
62            .width(100)
63            .layoutWeight(1)
64        } else {
65          List({ space: 12 }) {
66            LazyForEach(this.fileData, (item: FileModel, index?: number) => {
67              ListItem() {
68                if (index !== undefined) {
69                  this.FileItem(item, index)
70                }
71              }
72            }, (item: FileModel) => JSON.stringify(item))
73          }
74          .width('100%')
75          .scrollBar(BarState.Off)
76          .layoutWeight(1)
77          .backgroundColor(Color.White)
78          .borderRadius(24)
79          .padding({ top: 4, bottom: 4 })
80          .divider({ strokeWidth: 1, startMargin: 44, endMargin: 12 })
81        }
82
83        this.BottomView()
84      }
85      .padding({ left: 12, right: 12, bottom: 12 })
86      .height('100%')
87    }
88    .width('100%')
89    .height('100%')
90    .hideBackButton(false)
91    .titleMode(NavigationTitleMode.Mini)
92    .mode(NavigationMode.Stack)
93    .backgroundColor($r('app.color.light_gray'))
94    .hideToolBar(false)
95    .title($r('app.string.download'))
96  }
97
98  @Builder
99  FileItem(file: FileModel, index: number) {
100    Row() {
101      Row() {
102        if (file.fileType === FileType.FOLDER) {
103          Image($r('app.media.ic_files_folder'))
104            .size({ width: 24, height: 24 })
105            .objectFit(ImageFit.Contain)
106        } else if (file.fileType === FileType.IMAGE) {
107          Image($r('app.media.ic_public_picture'))
108            .size({ width: 24, height: 24 })
109            .objectFit(ImageFit.Contain)
110        } else if (file.fileType === FileType.MUSIC) {
111          Image($r('app.media.ic_public_music'))
112            .size({ width: 24, height: 24 })
113            .objectFit(ImageFit.Contain)
114        } else if (file.fileType === FileType.Video) {
115          Image($r('app.media.ic_public_video'))
116            .size({ width: 24, height: 24 })
117            .objectFit(ImageFit.Contain)
118        } else {
119          Image($r('app.media.ic_public_document'))
120            .size({ width: 24, height: 24 })
121            .objectFit(ImageFit.Contain)
122        }
123
124        Text(decodeURIComponent(file.name))
125          .fontSize(16)
126          .fontWeight(400)
127          .layoutWeight(1)
128          .maxLines(1)
129          .textOverflow({ overflow: TextOverflow.Ellipsis })
130          .margin({ left: 12 })
131      }
132      .layoutWeight(1)
133
134      Checkbox({ name: '', group: 'checkboxGroup' })
135        .select(this.checkList[index])
136        .selectedColor($r('app.color.button_blue'))
137        .margin({ left: 12 })
138        .hitTestBehavior(HitTestMode.None)
139    }
140    .width('100%')
141    .padding({ left: 12, right: 12 })
142    .height(48)
143    .onClick(() => {
144      this.fileCheck(index);
145    })
146  }
147
148  @Builder
149  BottomView() {
150    Column({ space: 12 }) {
151      if (this.isBackground && this.backDownTaskState !== BackgroundTaskState.NONE) {
152        Button() {
153          Row() {
154            Text(this.backDownTaskState === BackgroundTaskState.PAUSE ? $r('app.string.continue') : $r('app.string.pause'))
155              .fontColor(Color.White)
156              .fontSize(16)
157          }
158        }
159        .id('download_to')
160        .type(ButtonType.Capsule)
161        .height(45)
162        .width('100%')
163        .backgroundColor($r('app.color.button_blue'))
164        .onClick(() => {
165          requestDownload.pauseOrResume();
166        })
167        Button() {
168          Row() {
169            Text($r('app.string.cancel'))
170              .fontColor(Color.White)
171              .fontSize(16)
172          }
173        }
174        .id('download_to')
175        .type(ButtonType.Capsule)
176        .height(45)
177        .width('100%')
178        .backgroundColor($r('app.color.button_blue'))
179        .onClick(() => {
180          requestDownload.deleteAllBackTasks();
181        })
182      }
183      if (!this.isBackground || this.isBackground && this.backDownTaskState === BackgroundTaskState.NONE) {
184        Button() {
185          Row() {
186            if (!this.isBackground && this.isRunning) {
187              Text(`${this.progress}%`)
188                .fontColor(Color.White)
189                .fontSize(16)
190              Text($r('app.string.downloading'))
191                .fontColor(Color.White)
192                .fontSize(16)
193                .margin({ left: 12 })
194            } else {
195              Text($r('app.string.download'))
196                .fontColor(Color.White)
197                .fontSize(16)
198            }
199          }
200        }
201        .id('download_to')
202        .type(ButtonType.Capsule)
203        .height(45)
204        .width('100%')
205        .backgroundColor($r('app.color.button_blue'))
206        .onClick(() => {
207          if (!this.isRunning) {
208            this.folderDialogController.open();
209          }
210        })
211      }
212      Button($r('app.string.view_download_files'))
213        .id('view_download_files')
214        .type(ButtonType.Capsule)
215        .backgroundColor($r('sys.color.ohos_id_color_button_normal'))
216        .width('100%')
217        .fontSize(16)
218        .margin({ bottom: 12 })
219        .fontColor($r('app.color.btn_text_blue'))
220        .onClick(() => {
221          router.pushUrl({
222            url: 'pages/DownloadFiles'
223          });
224        })
225    }
226    .margin({ top: 12, left: 12, right: 12 })
227  }
228
229  aboutToAppear() {
230    this.isRunning = false;
231    this.isPause = false;
232    this.isGetData = true;
233    requestFiles.requestFiles().then((data: FileModel[]) => {
234      this.checkList = [];
235      this.isRunning = false;
236      this.fileData.dataArray = data;
237      this.fileData.dataArray.forEach((item: FileModel) => {
238        this.checkList.push(false);
239      })
240      this.isGetData = false;
241      this.fileData.notifyDataReload();
242    })
243    fileUtils.listFolders().then((folders: Array<string>) => {
244      this.downloadFolder = folders;
245    })
246  }
247
248  fileCheck(index: number) {
249    if (!this.isBackground) {
250      for (let i = 0; i < this.checkList.length; i++) {
251        if (i !== index) {
252          this.checkList[i] = false;
253        }
254      }
255    }
256    this.checkList[index] = !this.checkList[index];
257    logger.info(TAG, `this.checkList = ${JSON.stringify(this.checkList)}`);
258  }
259
260  download(folder: string) {
261    this.checkFile = [];
262    if (this.checkList === undefined) {
263      return;
264    }
265    logger.info(TAG, `this.checkList = ${JSON.stringify(this.checkList)}`);
266    for (let i = 0; i < this.checkList.length; i++) {
267      if (this.checkList[i]) {
268        let fileModel = this.fileData.getData(i);
269        logger.info(TAG, `fileModel = ${JSON.stringify(fileModel)}`);
270        fileModel.files.forEach((url: string) => {
271          let splitUrl = url.split('//')[1].split('/');
272          if (splitUrl[splitUrl.length-1] !== '') {
273            this.checkFile.push(url);
274          }
275        });
276      }
277    }
278    logger.info(TAG, `this.checkFile = ${JSON.stringify(this.checkFile)}`);
279    if (this.checkFile.length === 0) {
280      promptAction.showToast({ message: $r('app.string.check_file_tips'), bottom: TOAST_BOTTOM });
281      return;
282    }
283    this.progress = 0;
284    logger.info(TAG, `this.isBackground = ${JSON.stringify(this.isBackground)}`);
285    if (this.isBackground) {
286      this.isRunning = false;
287      this.backDownTaskState = BackgroundTaskState.RUNNING;
288      requestDownload.downloadFilesBackground(folder, this.checkFile);
289      this.checkFile = [];
290      this.checkList = [];
291      this.fileData.dataArray.forEach((item: FileModel) => {
292        this.checkList.push(false);
293      })
294      this.fileData.notifyDataReload();
295      promptAction.showToast({ message: $r('app.string.background_task_start'), bottom: TOAST_BOTTOM });
296    } else {
297      this.isRunning = true;
298      requestDownload.downloadFile(folder, this.checkFile[0], this.downloadFileCallback);
299    }
300  }
301
302  downloadFilesCallback = (downloadCount: number, isSuccess: boolean) => {
303    this.progress = downloadCount;
304    if (downloadCount === this.checkFile.length) {
305      this.downloadFinish(isSuccess);
306    }
307  }
308  downloadFileCallback = (progress: number, isSuccess: boolean) => {
309    this.progress = progress;
310    if (this.progress === 100) {
311      this.downloadFinish(isSuccess);
312    }
313  }
314
315  downloadFinish(isSuccess: boolean) {
316    this.isRunning = false;
317    this.checkFile = [];
318    this.checkList = [];
319    this.fileData.dataArray.forEach((item: FileModel) => {
320      this.checkList.push(false);
321    })
322    this.fileData.notifyDataReload();
323    let message = isSuccess ? $r('app.string.download_finish') : $r('app.string.download_fail');
324    promptAction.showToast({ message: message, bottom: TOAST_BOTTOM });
325  }
326}