1/* 2 * Copyright (c) 2024 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 { common } from '@kit.AbilityKit'; 17import { hilog } from '@kit.PerformanceAnalysisKit'; 18import { preferences } from '@kit.ArkData'; 19import { promptAction, router } from '@kit.ArkUI'; 20import { zlib } from '@kit.BasicServicesKit'; 21import fileio from '@ohos.fileio'; 22import { AddDialog } from '../common/AddDialog'; 23import { DeleteDialog } from '../common/DeleteDialog'; 24import { ZipLibSource } from '../model/DataSource'; 25 26const DOMAIN = 0xF811; 27const BUNDLE = 'ZipLib_'; 28const TAG: string = '[CompressFilesPage]'; 29let fileList: preferences.Preferences; 30 31@Entry 32@Component 33struct CompressFilesPage { 34 @State isInserted: boolean = false; 35 @State files: ZipLibSource = new ZipLibSource([]); 36 @State fileName: string = ''; 37 @State slectFileName: string[] = []; 38 @State zipFileNames: string[] = []; 39 @State fileContent: string = ''; 40 @State isSelect: boolean = false; 41 private path: string = ''; 42 private title: Resource = $r('app.string.CompressFiles'); 43 private dialogController: CustomDialogController = new CustomDialogController({ 44 builder: AddDialog({ 45 fileName: this.fileName, 46 fileContent: this.fileContent, 47 isInserted: this.isInserted, 48 createFile: async (isInserted: boolean, fileName: string, fileContent: string) => { 49 hilog.info(DOMAIN, TAG, BUNDLE + `enter the createFile`); 50 this.fileName = `${fileName}.txt`; 51 let isDuplication = this.files.fileData.includes(this.fileName); 52 hilog.info(DOMAIN, TAG, BUNDLE + `isInserted = ${isInserted} isDuplication = ${isDuplication}`); 53 if (!isInserted || isDuplication) { 54 return; 55 } 56 let fd = fileio.openSync(`${this.path}/${this.fileName}`, 0o100 | 0o2, 0o666); 57 let number = fileio.writeSync(fd, fileContent); 58 hilog.info(DOMAIN, TAG, BUNDLE + `fd = ${fd} number = ${number}`); 59 this.files.pushData(this.fileName); 60 hilog.info(DOMAIN, TAG, BUNDLE + `this.files = ${JSON.stringify(this.files.fileData)}`); 61 await fileList.put('fileNames', JSON.stringify(this.files.fileData)); 62 await fileList.flush(); 63 } 64 }), 65 autoCancel: true, 66 }) 67 private deleteDialogController: CustomDialogController = new CustomDialogController({ 68 builder: DeleteDialog({ 69 fileNames: this.zipFileNames, 70 isInserted: this.isInserted, 71 deleteFiles: async (isInserted: boolean, fileNames: Array<string>) => { 72 hilog.info(DOMAIN, TAG, BUNDLE + `enter the deleteFiles`); 73 if (!isInserted) { 74 return; 75 } 76 if (this.zipFileNames.length == 0) { 77 promptAction.showToast({ 78 message: $r('app.string.delete_file_tip'), 79 bottom: '11%' 80 }); 81 return; 82 } 83 for (let index = 0; index < this.files.fileData.length; index++) { 84 for (let i = 0; i < this.zipFileNames.length; i++) { 85 if (this.zipFileNames[i] == this.files.fileData[index]) { 86 this.files.deleteData(index); 87 await fileList.put('fileNames', JSON.stringify(this.files.fileData)); 88 await fileList.flush(); 89 } 90 } 91 } 92 this.zipFileNames.length = 0; 93 promptAction.showToast({ 94 message: $r('app.string.delete_file_success'), 95 bottom: '11%' 96 }); 97 } 98 }), 99 autoCancel: true, 100 }) 101 102 async aboutToAppear() { 103 fileList = await preferences.getPreferences(getContext(this), 'fileList'); 104 let ctx = getContext(this) as common.Context; 105 this.path = ctx.filesDir; 106 let value = await fileList.get('fileNames', ''); 107 this.files.fileData = JSON.parse(`${value}`); 108 this.files.notifyDataReload(); 109 this.zipFileNames.length = 0; 110 this.zipFileNames = this.files.fileData.filter(item => item.endsWith('.zip')); 111 } 112 113 async zipcompressFiles(path: string, zipfileNames: Array<string>): Promise<void> { 114 let files: string[] = []; 115 for (let index = 0; index < zipfileNames.length; index++) { 116 files[index] = `${path}/${zipfileNames[index]}`; 117 } 118 let zipFiles = Array.from(files); 119 hilog.debug(DOMAIN, TAG, BUNDLE + `zipFile = ${zipFiles}`); 120 let newName = `test_` + this.zipFileNames.length + `.zip`; 121 let zipOutFile = `${this.path}/${newName}`; 122 hilog.debug(DOMAIN, TAG, BUNDLE + `zipOutFile = ${zipOutFile}`); 123 124 if (this.files.fileData.includes(newName)) { 125 promptAction.showToast({ 126 message: $r('app.string.warning_failed'), 127 bottom: '11%' 128 }); 129 return; 130 } 131 try { 132 await zlib.compressFiles(zipFiles, zipOutFile, {}).then(data => { 133 zlib.getOriginalSize(zipOutFile).then((num) => { 134 promptAction.showToast({ 135 message: $r('app.string.CompressFiles_success_size', num), 136 bottom: '11%' 137 }); 138 }) 139 this.files.pushData(`${newName}`); 140 this.zipFileNames.push(newName); 141 }) 142 } catch { 143 promptAction.showToast({ 144 message: $r('app.string.CompressFiles_failure'), 145 bottom: '11%' 146 }); 147 } 148 await fileList.put('fileNames', JSON.stringify(this.files.fileData)); 149 await fileList.flush(); 150 } 151 152 build() { 153 Column() { 154 Column() { 155 Row() { 156 Row() { 157 Image($r('app.media.icon_back')) 158 .size({ height: '71%' }) 159 .objectFit(ImageFit.Contain) 160 .onClick(() => { 161 router.pushUrl({ 162 url: 'zlib/ZLibInterfaceListPage' 163 }); 164 }) 165 Text(this.title) 166 .fontSize(20) 167 .margin({ left: 8 }) 168 .fontWeight(FontWeight.Bold) 169 } 170 171 Row() { 172 Image($r('app.media.icon_delete')) 173 .size({ height: '71%' }) 174 .id('deleteFile') 175 .objectFit(ImageFit.Contain) 176 .onClick(() => { 177 this.deleteDialogController.open(); 178 }) 179 180 Image($r('app.media.add')) 181 .size({ height: '71%' }) 182 .id('addFile') 183 .margin({ left: '3%' }) 184 .objectFit(ImageFit.Contain) 185 .onClick(() => { 186 this.dialogController.open(); 187 }) 188 } 189 } 190 .justifyContent(FlexAlign.SpaceBetween) 191 .width('91%') 192 .height('9.75%') 193 .backgroundColor($r('app.color.backGrounding')) 194 195 List({ initialIndex: 0 }) { 196 LazyForEach(this.files, (item: string, index: number) => { 197 ListItem() { 198 Row() { 199 Row() { 200 Image(item.includes('.zip') ? $r('app.media.zip') : $r('app.media.file')) 201 .size({ height: '66.7%' }) 202 .objectFit(ImageFit.Contain) 203 Column() { 204 Text(item) 205 .width('50%') 206 .fontSize(16) 207 .margin({ left: 16 }) 208 } 209 } 210 211 Checkbox() 212 .visibility(item.includes('.zip') ? Visibility.Hidden : Visibility.Visible) 213 .width('6%') 214 .select(this.slectFileName.indexOf(item) != -1 ? true : false) 215 .id('file_' + index) 216 .selectedColor($r('app.color.checkbox_color')) 217 .shape(CheckBoxShape.CIRCLE) 218 .onChange((value: boolean) => { 219 if (value) { 220 this.isSelect = true; 221 this.slectFileName.push(item); 222 } else { 223 this.isSelect = false; 224 let index = this.slectFileName.indexOf(item); 225 if (index !== -1) { 226 this.slectFileName.splice(index, 1); 227 } 228 } 229 }) 230 } 231 .justifyContent(FlexAlign.SpaceBetween) 232 .padding({ right: 12, left: 12 }) 233 .width('100%') 234 .height('14.2%') 235 .borderRadius(16) 236 .backgroundColor($r('app.color.start_window_background')) 237 } 238 .margin({ bottom: 12 }) 239 }, (item: string) => item) 240 } 241 .margin({ top: 8 }) 242 .height('85.875%') 243 .width('91%') 244 .backgroundColor($r('app.color.index_bg')) 245 } 246 .height('80%') 247 .width('100%') 248 249 250 Column() { 251 Text($r('app.string.tip_CompressFiles')) 252 .textAlign(TextAlign.Start) 253 .fontSize(12) 254 .fontColor($r('app.color.tip_Gzip_backeGround')) 255 .width('86.4%') 256 .height('22.3%') 257 .margin({ bottom: 24 }) 258 259 Row() { 260 Button($r('app.string.zip')) 261 .id('compress') 262 .height('100%') 263 .width('100%') 264 .fontSize(16) 265 .fontFamily('HarmonyHeiTi') 266 .type(ButtonType.Capsule) 267 .backgroundColor($r('app.color.button_color')) 268 .fontColor($r('app.color.text_white_color')) 269 .borderRadius(20) 270 .onClick(() => { 271 if (this.isSelect) { 272 this.zipcompressFiles(this.path, this.slectFileName); 273 } 274 }) 275 } 276 .margin({ bottom: 16 }) 277 .height('28%') 278 .width('91%') 279 } 280 .justifyContent(FlexAlign.End) 281 .alignItems(HorizontalAlign.Center) 282 .height('20%') 283 .width('100%') 284 } 285 .height('100%') 286 .width('100%') 287 .backgroundColor($r('app.color.index_bg')) 288 } 289} 290