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}