• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2023 Shenzhen Kaihong Digital Industry Development 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 */
15import MyWatcher from '../filemanager/fileFs/MyWatcher';
16import common from '@ohos.app.ability.common';
17import fs from '@ohos.file.fs';
18import router from '@ohos.router';
19import { Logger, sleep, bufferToString } from '../common/Common';
20
21const TAG: string = '[FileIO].[WatcherFile]';
22
23@CustomDialog
24export struct DeleteDialog {
25  @Link hitText: string
26  @Link currentIndex: number
27  controller: CustomDialogController
28  cancel: () => void = () => {}
29  confirm: (index: number) => void = () => {}
30
31  build() {
32    Column() {
33      Text(this.hitText)
34        .fontSize(20)
35        .fontColor('#182431')
36        .textAlign(TextAlign.Center)
37        .lineHeight(26)
38        .fontWeight(500)
39        .width(288)
40        .height(52)
41        .margin({ top: 24, left: 24, right: 24 })
42
43      Flex({ justifyContent: FlexAlign.SpaceAround }) {
44        Row() {
45          Text($r('app.string.cancel'))
46            .fontSize(16)
47            .fontColor('#007DFF')
48            .textAlign(TextAlign.Center)
49            .lineHeight(22)
50            .fontWeight(500)
51            .width(136)
52            .backgroundColor(0xffffff)
53            .onClick(() => {
54              this.controller.close()
55              this.cancel()
56            })
57          Text('|')
58            .backgroundColor(0xffffff)
59            .fontColor(Color.Gray)
60            .height(24)
61          Text($r('app.string.deleteFile'))
62            .fontSize(16)
63            .fontColor('#FA2A2D')
64            .textAlign(TextAlign.Center)
65            .lineHeight(22)
66            .fontWeight(500)
67            .width(136)
68            .backgroundColor(0xffffff)
69            .id('deleteWatcher')
70            .onClick(() => {
71              this.controller.close()
72              this.confirm(this.currentIndex)
73            })
74        }
75      }
76      .margin({ top: 9, bottom: 25 })
77    }
78    .backgroundColor(0xffffff)
79    .width('80%')
80    .height(132)
81  }
82}
83
84@Entry
85@Component
86struct Watcher {
87  @State message: Resource = $r('app.string.watcherFileText');
88  @State myContext: Context = getContext(this) as common.UIAbilityContext;
89  @State inputNameValue: string = 'text.txt';
90  @State inputContentValue: string = 'abcdefg';
91  @State currentIndex: number = 1;
92  @State currentDelFileName: string = '';
93  @State currentFileName: string = '';
94  @State currentFileSize: number = 0;
95  @State currentFileContent: string = '';
96  @State eachEvent: string = '';
97  @State isFromEdit: boolean = false;
98  @State editFlag: boolean = true;
99  @State watcherEvent: Array<string> = [
100    'IN_ACCESS',
101    'IN_MODIFY',
102    'IN_ATTRIB',
103    'IN_CLOSE_WRITE',
104    'IN_CLOSE_NOWRITE',
105    'IN_OPEN',
106    'IN_MOVED_FROM',
107    'IN_MOVED_TO',
108    'IN_CREATE',
109    'IN_DELETE',
110    'IN_DELETE_SELF',
111    'IN_MOVE_SELF',
112  ];
113  @State filePathSize: Array<number> = [];
114  @State showFilePath: Array<string> = [];
115  @StorageLink('eventLog') eventLog: string = 'unknown';
116  @StorageLink('fileNameLog') fileNameLog: string = 'unknown';
117  @StorageLink('cookieLog') cookieLog: string = 'unknown';
118  @StorageLink('newFileName') newFileName: string = '';
119  @StorageLink('newFileContent') newFileContent: string = '';
120  @StorageLink('eventArray') eventArray: Array<string> = [];
121  @StorageLink('addIndex') addIndex: number = 10;
122  public baseDir: string = AppStorage.get<string>('sanBoxFileDir') as string;
123
124  @Builder itemEnd(index: number) { // 侧滑后尾端出现的组件
125    Row() {
126      Image($r('app.media.ic_edit'))
127        .width(40)
128        .height(40)
129        .margin({ left: 16, right: 8 })
130        .id('editFile')
131        .onClick(() => {
132          this.currentIndex = index;
133          this.currentFileName = this.showFilePath[index];
134          let length = this.currentFileName.length;
135          this.currentFileName = this.currentFileName.substring(0, length - 4);
136          let filePath = this.baseDir + '/watcherDir/' + this.showFilePath[index];
137          this.currentFileSize = fs.statSync(filePath).size;
138          let file = fs.openSync(filePath, fs.OpenMode.READ_WRITE);
139          let buf = new ArrayBuffer(4096);
140          fs.readSync(file.fd, buf, {
141            offset: 0
142          });
143          this.currentFileContent = bufferToString(buf);
144          router.pushUrl({
145            url: 'pages/EditFile',
146            params: {
147              fileName: this.currentFileName,
148              fileSize: this.currentFileSize,
149              fileContent: this.currentFileContent,
150            }
151          }, router.RouterMode.Standard);
152
153        });
154
155      Image($r('app.media.ic_delete'))
156        .width(40)
157        .height(40)
158        .margin(1)
159        .id('deleteFile')
160        .onClick(() => {
161          this.currentDelFileName = this.showFilePath[index];
162          this.currentIndex = index;
163          let lastIndex = this.currentDelFileName.length - 4;
164          let isDelDile = AppStorage.get<string>('isDelFile') as string;
165          this.currentDelFileName = isDelDile + this.currentDelFileName.substring(0, lastIndex) + '?';
166          this.deleteDialog.open();
167        });
168    }
169    .padding(1)
170    .justifyContent(FlexAlign.SpaceEvenly)
171  }
172
173  private select: number = 1;
174  private selectDel: number = 1;
175  private isDelStr: Resource = $r('app.string.isDelFile');
176  myWatcher: MyWatcher = new MyWatcher();
177  scroller: Scroller = new Scroller();
178  deleteDialog: CustomDialogController = new CustomDialogController({
179    builder: DeleteDialog({
180      hitText: $currentDelFileName,
181      cancel: this.onCancel,
182      confirm: (index: number): void => this.onDelete(index),
183      currentIndex: $currentIndex,
184    }),
185    cancel: () => {},
186    alignment: DialogAlignment.Bottom,
187    offset: { dx: 0, dy: -12 },
188    autoCancel: true
189  })
190
191  onCancel(): void {
192    Logger.info('cancel');
193  };
194
195  onDelete(index: number): void {
196    this.myWatcher.deleteFileToWatcher(this.showFilePath[index]);
197    this.filePathSize.splice(index, 1);
198    this.showFilePath.splice(index, 1);
199  }
200
201  onPageShow(): void {
202    Logger.info('aboutToDisappear eventArray:  ' + this.eventArray.length);
203    let filePathDir = this.baseDir + '/watcherDir';
204    Logger.info('filePathDir = ' + filePathDir);
205    let filenames = fs.listFileSync(filePathDir);
206    Logger.info('listFile succeed');
207    for (let i = 0; i < filenames.length; i++) {
208      Logger.info('filename: %s', filenames[i]);
209      this.showFilePath[i] = filenames[i];
210      let filePath = filePathDir + '/' + filenames[i];
211      this.filePathSize[i] = fs.statSync(filePath).size;
212    }
213  }
214
215  onPageHide(): void {
216    Logger.info('onPageHide eventArray:  ' + this.eventArray.length);
217  }
218
219  aboutToDisappear(): void {
220    try {
221      for (let i = 0; i < this.myWatcher.watcherList.length; i++) {
222        Logger.info('aboutToDisappear this.myWatcher.watcherList.length:  ' + this.myWatcher.watcherList.length);
223        this.myWatcher.stopWatcher(this.myWatcher.watcherList[i], i);
224      }
225    } catch (e) {
226      Logger.error('stopwatcher fail and error: ' + JSON.stringify(e));
227    }
228  }
229
230  aboutToAppear(): void {
231    Logger.info('aboutToAppear eventArray:  ' + this.eventArray.length);
232  }
233
234  build() {
235    Scroll(this.scroller) {
236      Row() {
237        Column() {
238          Row() {
239            Image($r('app.media.ic_back'))
240              .width(24)
241              .height(24)
242              .align(Alignment.Start)
243              .margin({ top: 13, bottom: 15, left: 26, right: 18 })
244              .id('backIndex')
245              .onClick(() => {
246                router.pushUrl({
247                  url: 'pages/Index',
248                }, router.RouterMode.Standard);
249              })
250            Text(this.message)
251              .fontSize(20)
252              .fontColor('#182431')
253              .textAlign(TextAlign.Start)
254              .lineHeight(28)
255              .fontWeight(700)
256              .margin({ top: 13, bottom: 15 })
257
258          }
259          .width('100%')
260          .height(56)
261          .backgroundColor('#f1f3f5')
262          .align(Alignment.Start)
263
264          Flex({ direction: FlexDirection.Column }) {
265            Flex({ direction: FlexDirection.Row, justifyContent: FlexAlign.SpaceBetween }) {
266              Row() {
267                Text($r('app.string.watcherTitleText'))
268                  .fontSize(14)
269                  .margin({ top: 19.5, bottom: 9.5 })
270                  .lineHeight(19)
271                  .width(176)
272                  .fontColor('#182431')
273                  .fontWeight(500)
274                  .textAlign(TextAlign.Start)
275                  .backgroundColor('#f1f3f5')
276                  .opacity(0.6)
277              }
278              .width('61%')
279              .padding({ left: 24, right: 52 })
280              .backgroundColor('#f1f3f5')
281
282              Row() {
283                Text($r('app.string.addFile'))
284                  .margin({ top: 19.5, bottom: 9.5 })
285                  .fontSize(14)
286                  .height(48)
287                  .backgroundColor('#f1f3f5')
288                  .fontColor('#007DFF')
289                  .textAlign(TextAlign.End)
290                  .fontWeight(500)
291                  .width(84)
292                  .id('addFile')
293                  .onClick(() => {
294                    let filePathDir = this.baseDir + '/watcherDir/';
295                    let fileName = `TestFile${this.addIndex}.txt`;
296                    this.addIndex++;
297                    this.myWatcher.addFileToWatcher(fileName);
298                    let filePath = filePathDir + fileName;
299                    let res = fs.accessSync(filePath);
300                    this.showFilePath.push(fileName);
301                    if (res) {
302                      this.filePathSize.push(fs.statSync(filePath).size);
303                      Logger.info('addFileToWatcher this.filePathSize size = ' + fs.statSync(filePath).size);
304                    }
305                  })
306              }
307              .justifyContent(FlexAlign.SpaceBetween)
308              .height(48)
309              .margin({ right: 24 })
310              .width('30%')
311              .backgroundColor('#f1f3f5')
312            }
313            .width('100%')
314            .backgroundColor('#f1f3f5')
315
316            Column() {
317              List({ space: 12, initialIndex: 0 }) {
318                ForEach(this.showFilePath, (item: string, index?: number) => {
319                  ListItem() {
320                    Row() {
321                      Text(item)
322                        .fontSize(16)
323                        .fontColor('#182431')
324                        .width('70%')
325                        .lineHeight(22)
326                        .textAlign(TextAlign.Start)
327                        .fontWeight(500)
328                        .margin({ left: 12 })
329                        .borderRadius(10)
330                        .backgroundColor(0xFFFFFF)
331                        .id('item' + index)
332                      if (index != undefined) {
333                        Text(JSON.stringify(this.filePathSize[index]) + 'B')
334                          .fontSize(14)
335                          .width('24.5%')
336                          .lineHeight(19)
337                          .textAlign(TextAlign.End)
338                          .fontColor('#182431')
339                          .fontWeight(400)
340                          .opacity(0.6)
341                          .margin({ right: 12 })
342                          .borderRadius(10)
343                          .backgroundColor(0xFFFFFF)
344                      }
345                    }
346                    .borderRadius(20)
347                    .width('94%')
348                    .height(56)
349                    .backgroundColor(0xFFFFFF)
350                  }
351                  .swipeAction({ end: () : void => this.itemEnd(index) }) // 设置左滑属性
352                }, (item: string) => item)
353              }
354              .id('list')
355              .alignListItem(ListItemAlign.Center)
356              .scrollBar(BarState.Auto)
357            }
358            .padding({ top: 5 })
359            .backgroundColor('#f1f3f5')
360            .width('100%')
361            .height(436)
362            .align(Alignment.Center)
363
364            Column() {
365              Row() {
366                Text($r('app.string.logTitle'))
367                  .fontSize(14)
368                  .fontColor('#182431')
369                  .textAlign(TextAlign.Start)
370                  .lineHeight(19)
371                  .fontWeight(500)
372                  .margin({ top: 19.5, left: 24 })
373                  .width(176)
374                  .opacity(0.6)
375              }
376              .width('100%')
377              .align(Alignment.Start)
378
379              Column() {
380                Column() {
381                  Text(`event: ${this.eventLog}`)
382                    .fontSize(16)
383                    .fontColor('#182431')
384                    .fontWeight(400)
385                    .width('100%')
386                  Text(`fileName: ${this.fileNameLog}`)
387                    .fontSize(16)
388                    .fontColor('#182431')
389                    .fontWeight(400)
390                    .width('100%')
391                  Text(`cookie: ${this.cookieLog}`)
392                    .fontSize(16)
393                    .fontColor('#182431')
394                    .fontWeight(400)
395                    .width('100%')
396                }
397                .margin({ top: 8, left: 12, right: 12, bottom: 8 })
398                .height(64)
399              }
400              .borderRadius(20)
401              .height(80)
402              .margin({ top: 9.5, left: 16, right: 16 })
403              .backgroundColor('#ffffff')
404
405              Row({ space: 2 }) {
406                Column() {
407                  Button($r('app.string.stopWatcher'))
408                    .fontSize(16)
409                    .width(144)
410                    .height(40)
411                    .backgroundColor('#e6e9eb')
412                    .fontColor('#007DFF')
413                    .fontWeight(500)
414                    .margin({ right: 24 })
415                    .id('stopWatcher')
416                    .onClick(() => {
417                      let showEventArray : string[] = [];
418                      Logger.info('onClick this.eventArray.length = ' + this.eventArray.length);
419                      let j = 0;
420                      for (let i = 0; i < this.eventArray.length; i++) {
421                        Logger.info('onClick this.eventArray[' + i + '] = ' + this.eventArray[i]);
422                        if (this.eventArray[i] === 'test') {
423                          continue;
424                        }
425                        Logger.info('onClick2 this.eventArray[' + i + '] = ' + this.eventArray[i]);
426                        showEventArray[j] = this.eventArray[i];
427                        j++;
428                        Logger.info('onClick showEventArray[' + j + '] = ' + showEventArray[j]);
429                      }
430                      if (showEventArray.length === 0) {
431                        AlertDialog.show({
432                          message: '当前无监听,请先添加监听'
433                        })
434                        return;
435                      }
436                      TextPickerDialog.show({
437                        range: showEventArray,
438                        selected: this.selectDel,
439                        onAccept: (value: TextPickerResult) => {
440                          this.selectDel = Number(value.index);
441                          Logger.info('TextPickerDialog:onChange() this.selectDel = ' + this.selectDel);
442                          Logger.info('TextPickerDialog:onChange() value = ' + JSON.stringify(value));
443                          this.myWatcher.stopWatcher(this.myWatcher.watcherList[this.selectDel], this.selectDel);
444                          this.eventArray.splice(this.selectDel, 1);
445                          showEventArray.splice(this.selectDel, 1);
446                        },
447                      })
448                    })
449                }
450                .width('50%')
451                .align(Alignment.Start)
452
453                Column() {
454                  Button($r('app.string.addWatcher'))
455                    .fontSize(16)
456                    .width(144)
457                    .height(40)
458                    .fontColor('#FFFFFF')
459                    .fontWeight(500)
460                    .id('addWatcher')
461                    .onClick(() => {
462                      TextPickerDialog.show({
463                        range: this.watcherEvent,
464                        selected: this.select,
465                        onAccept: (value: TextPickerResult) => {
466                          this.select = Number(value.index);
467                          Logger.info('TextPickerDialog:onChange() this.select = ' + this.select);
468                          Logger.info('TextPickerDialog:onChange() value = ' + JSON.stringify(value));
469                          Logger.info('TextPickerDialog:onChange() this.select = ' + this.select);
470                          this.eachEvent = this.watcherEvent[this.select];
471                          Logger.info('TextPickerDialog:onChange() this.eachEvent = ' + this.eachEvent);
472                          this.myWatcher.startWatcher(this.eachEvent);
473                          Logger.info(`onSelect-${this.eachEvent} end`);
474                          this.eventArray.push(this.eachEvent); // 新增列表项数据
475                        },
476                      })
477                    })
478                }
479                .width('50%')
480                .align(Alignment.End)
481              }
482              .align(Alignment.Center)
483              .width('70%')
484              .margin({ top: 24, left: 24, right: 24, bottom: 24 })
485            }
486            .backgroundColor('#f1f3f5')
487            .width('100%')
488            .height(216)
489          }
490          .width('100%')
491        }
492        .width('100%')
493      }
494      .height('100%')
495    }
496    .id('scroller')
497  }
498}