• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2022 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 DateUtil from '@ohos/utils/src/main/ets/default/baseUtil/DateUtil'
17import FolderData from '@ohos/utils/src/main/ets/default/model/databaseModel/FolderData'
18import NoteData from '@ohos/utils/src/main/ets/default/model/databaseModel/NoteData'
19import {
20  TableName,
21  NoteTableColumn,
22  SysDefFolderUuid,
23  Favorite,
24  Delete,
25  Top,
26  NoteType
27} from '@ohos/utils/src/main/ets/default/model/databaseModel/EnumData'
28import { NoteDataMoveDialog, DeleteDialog } from './CusDialogComp'
29import RdbStoreUtil from '@ohos/utils/src/main/ets/default/baseUtil/RdbStoreUtil'
30import prompt from '@system.prompt'
31import NoteUtil from '@ohos/utils/src/main/ets/default/baseUtil/NoteUtil'
32import FolderUtil from '@ohos/utils/src/main/ets/default/baseUtil/FolderUtil'
33import SearchModel from '@ohos/utils/src/main/ets/default/model/searchModel/SearchModel'
34import { LogUtil } from '@ohos/utils/src/main/ets/default/baseUtil/LogUtil'
35import router from '@system.router';
36import inputMethod from '@ohos.inputMethod';
37
38const TAG = "NoteListComp"
39
40async function routePage() {
41  let options = {
42    uri: 'pages/NoteContentHome'
43  }
44  try {
45    await router.push(options)
46  } catch (err) {
47    LogUtil.info(TAG, "fail callback")
48  }
49}
50
51// Note list component
52@Component
53export struct NoteListComp {
54  @StorageLink('AllFolderArray') AllFolderArray: FolderData[] = AppStorage.Link('AllFolderArray')
55  @Consume('SelectedFolderData') selectedFolderData: FolderData
56  @Consume('Search') search: boolean
57  controllerShow: WebviewController
58  @Consume('AsideWidth') asideWidth: number
59
60  build() {
61    Flex({ direction: FlexDirection.Column }) {
62      Flex({ direction: FlexDirection.Column }) {
63        NoteOverViewComp({ controllerShow: this.controllerShow })
64        Column() {
65        }
66        .height(this.search ? 15 : 0)
67
68        NoteItemListComp({ controllerShow: this.controllerShow })
69      }
70      .width('100%')
71      .flexShrink(1)
72
73      Column() {
74        OperateNoteCompForPortrait()
75      }
76      .flexShrink(0)
77    }
78    .height('100%')
79    .width('100%')
80  }
81
82  aboutToAppear(): void {
83    AppStorage.SetOrCreate('isUpdate', false)
84    LogUtil.info(TAG, "aboutToAppear")
85  }
86
87  aboutToDisappear(): void {
88    LogUtil.info(TAG, "aboutToDisappear")
89  }
90}
91
92@Component
93struct NoteOverViewComp {
94  @StorageLink('AllNoteArray') AllNoteArray: NoteData[] = AppStorage.Link('AllNoteArray')
95  @StorageLink('breakPoint') breakPoints: string = AppStorage.Get('breakPoint')
96  @StorageLink('CheckedNoteArray') CheckedNoteArray: NoteData[] = []
97  @Consume('SelectedFolderData') selectedFolderData: FolderData
98  @Consume('RefreshFlag') refreshFlag: number
99  @Consume('SectionStatus') sectionStatus: number
100  @Consume("Longpress") longpress: boolean
101  @Consume('ExpandStatus') expandStatus: boolean
102  @Consume('Search') search: boolean
103  @Consume('PortraitModel') portraitModel: boolean
104  controllerShow: WebviewController
105  @State noteNumber: number = undefined
106  @StorageLink('isUpdate') @Watch('notesNumberChange') isUpdate: boolean = false
107  @Consume('AsideWidth') asideWidth: number
108  @State isShow: boolean = false
109
110  notesNumberChange() {
111    let noteNumbers = FolderUtil.getNoteCount(AppStorage.Get('AllNoteArray'), this.selectedFolderData.uuid)
112    if (noteNumbers == 0) {
113      this.isShow = false
114    } else {
115      this.isShow = true
116    }
117  }
118
119  build() {
120    Flex({ justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Center }) {
121      Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center }) {
122        Column() {
123          Image($r("app.media.suojin_back"))
124            .height(24)
125            .width(24)
126            .responseRegion({
127              x: -15.0,
128              y: -15.0,
129              width: 54,
130              height: 54
131            })
132            .margin({ right: 24 }) // 两分栏时缩进图片与右边有个24的间距
133            .visibility(this.breakPoints == 'lg' && this.sectionStatus == 3 ? Visibility.None : Visibility.Visible)
134            .onClick(() => {
135              if (this.breakPoints == 'sm' || this.breakPoints == 'md') {
136                animateTo({ duration: 200 }, () => {
137                  this.expandStatus = !this.expandStatus
138                })
139              } else {
140                this.asideWidth = 200
141                this.sectionStatus = (this.sectionStatus == 3 ? 2 : 3)
142                // save continue data
143                AppStorage.SetOrCreate<number>('ContinueSection', this.sectionStatus)
144                LogUtil.info(TAG, "NoteOverViewComp, set continue section success")
145              }
146            })
147        }.alignItems(HorizontalAlign.Center)
148
149        Flex({
150          direction: FlexDirection.Column,
151          wrap: FlexWrap.Wrap,
152          justifyContent: FlexAlign.Center,
153          alignItems: ItemAlign.Start
154        }) {
155          Text(FolderUtil.getFolderText(this.selectedFolderData))
156            .id(this.isUpdate + '')
157            .maxLines(1)
158            .fontSize(30)
159            .fontColor($r("app.color.all_notes_font_color"))
160            .fontWeight(FontWeight.Medium)
161            .textOverflow({ overflow: TextOverflow.Ellipsis })
162          Row() {
163            Text(FolderUtil.getNoteCount(AppStorage.Get('AllNoteArray'), this.selectedFolderData.uuid).toString())
164              .id(this.isUpdate + '')
165              .maxLines(1)
166              .fontSize(14)
167              .fontColor($r("app.color.num_of_notes_font_color"))
168            Text($r("app.string.noteslist"))
169              .fontSize(14)
170              .fontColor($r("app.color.num_of_notes_font_color"))
171              .textOverflow({ overflow: TextOverflow.Ellipsis })
172          }
173          .margin({ top: 5 })
174          .visibility(this.isShow ? Visibility.Visible : Visibility.None)
175        }.visibility(this.longpress ? Visibility.None : Visibility.Visible)
176
177        Row() {
178          Image($r("app.media.cross"))
179            .height(24)
180            .width(24)
181            .responseRegion({
182              x: -15.0,
183              y: -15.0,
184              width: 54,
185              height: 54
186            })
187            .onClick(() => {
188              this.longpress = false
189              this.refreshFlag = (this.refreshFlag == 0 ? 1 : 0)
190              NoteUtil.unsetAllNotesChecked(this.CheckedNoteArray)
191            })
192          Text(this.CheckedNoteArray.length == 0 ? $r("app.string.none_selected") : $r("app.string.selected", this.CheckedNoteArray.length))
193            .fontSize(20)
194            .fontColor($r("app.color.note_selected_font_color"))
195            .margin({ left: 16 })
196            .textOverflow({ overflow: TextOverflow.Ellipsis })
197            .fontWeight(FontWeight.Medium)
198        }.alignItems(VerticalAlign.Center)
199        .visibility(this.longpress ? Visibility.Visible : Visibility.None)
200      }.padding({ top: 8, bottom: 8 })
201      .height('100%')
202
203      AddNoteComp({ controllerShow: this.controllerShow })
204      OperateNoteComp({ controllerShow: this.controllerShow })
205      Text(this.refreshFlag.toString()).visibility(Visibility.None)
206    }
207    .width('100%')
208    .height(82)
209    .padding({
210      left: this.sectionStatus == 2 ? 24 : 36,
211      right: 24
212    }) // 两分栏时缩进图标与左侧不需要间距
213    .visibility(this.search ? Visibility.None : Visibility.Visible)
214  }
215}
216
217@Component
218export struct NoteItemComp {
219  public noteItem: NoteData
220  public spans: any[]
221  controllerShow: WebviewController
222  @Consume('SelectedFolderData') selectedFolderData: FolderData
223  @Consume('SelectedNoteData') selectedNoteData: NoteData
224  @StorageLink('AllFolderArray') AllFolderArray: FolderData[] = AppStorage.Link('AllFolderArray')
225  @StorageLink('CheckedNoteArray') CheckedNoteArray: NoteData[] = []
226  @Consume('ChooseNote') chooseNote: boolean
227  @Consume('RefreshFlag') refreshFlag: number
228  @Consume('Search') search: boolean
229  @Consume('selectedAll') selectedAll: boolean
230  @Consume('PortraitModel') portraitModel: boolean
231  @State isChecked: boolean = undefined
232  @Consume('Longpress') @Watch('isLongPress') longpress: boolean
233  @StorageLink('isUpdate') isUpdate: boolean = false
234
235  isLongPress() {
236    if (this.longpress) {
237      this.isChecked = false
238    }
239  }
240
241  updateAndGetChecked() {
242    this.isChecked = NoteUtil.isNoteChecked(this.CheckedNoteArray, this.noteItem)
243    return this.isChecked
244  }
245
246  build() {
247    Flex({ justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Center }) {
248      Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center }) {
249        Text(JSON.stringify(this.refreshFlag)).visibility(Visibility.None) // 用于强制刷新使用
250        Column({ space: 2 }) {
251          Row({ space: 8 }) {
252            Image($r("app.media.verticalBar"))
253              .id(this.isUpdate + '')
254              .height(16)
255              .width(4)
256              .fillColor(NoteUtil.getVerticalBarBgColor(AppStorage.Get('AllFolderArray'), this.noteItem.folder_uuid))
257            Text(this.noteItem.title)
258              .fontSize(16)
259              .maxLines(1)
260              .textOverflow({ overflow: TextOverflow.Ellipsis })
261          }
262
263          Row({ space: 4 }) {
264            Text(DateUtil.formateDateForNoteTitle(new Date(this.noteItem.modified_time)))
265              .id(this.isUpdate + '')
266              .maxLines(1)
267              .fontSize(14)
268              .fontColor($r("app.color.list_modified_time_font_color"))
269              .fontWeight(FontWeight.Regular)
270              .textOverflow({ overflow: TextOverflow.Ellipsis })
271            Image($r("app.media.favorite"))
272              .height(16)
273              .width(16)
274              .visibility(this.noteItem.is_favorite == Favorite.Yes ? Visibility.Visible : Visibility.None)
275            Image($r("app.media.topped"))
276              .height(16)
277              .width(16)
278              .visibility(this.noteItem.is_top == Top.Yes ? Visibility.Visible : Visibility.None)
279          }
280          .padding({ left: 12 })
281        }.alignItems(HorizontalAlign.Start)
282      }.flexShrink(1)
283
284      Flex({ justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Center }) {
285        Stack({ alignContent: Alignment.Center }) {
286          Image(this.noteItem.content_img)
287            .id(this.isUpdate + '')
288            .height(47)
289            .width(47)
290            .borderRadius(12)
291            .border({ width: 0.5, color: '#19182431' })
292            .visibility(this.noteItem.content_img ? Visibility.Visible : Visibility.None)
293        }
294
295        Stack({ alignContent: Alignment.Center }) {
296          Image($r("app.media.unChecked"))
297            .height(24)
298            .width(24)
299          Image($r("app.media.checked"))
300            .width(24)
301            .height(24)
302            .visibility(this.updateAndGetChecked() ? Visibility.Visible : Visibility.None)
303            .id(this.isUpdate + '')
304        }.width(24)
305        .height(24)
306        .visibility(this.longpress ? Visibility.Visible : Visibility.None)
307      }
308      .flexShrink(0)
309      .height(48)
310      .width(this.longpress ? 80 : 48)
311    }
312    .width('100%')
313    .height(72)
314    .padding({
315      left: 16,
316      right: 12,
317      top: 4,
318      bottom: 4
319    })
320    .borderRadius(24)
321    .linearGradient({
322      direction: GradientDirection.Right,
323      colors: this.selectedNoteData?.uuid == this.noteItem.uuid ? [[0xffcdae, 0.0], [0xFfece2, 1.0]] : [[0xffffff, 0.0], [0xffffff, 1.0]]
324    })
325    .onClick(() => {
326      if (this.search) {
327        this.search = false
328        AppStorage.SetOrCreate<boolean>('Search', this.search)
329        return
330      }
331      if (this.longpress) {
332        if (NoteUtil.isNoteChecked(this.CheckedNoteArray, this.noteItem)) {
333          NoteUtil.unsetNoteChecked(this.CheckedNoteArray, this.noteItem)
334          this.refreshFlag = (this.refreshFlag == 0 ? 1 : 0)
335          this.isChecked = NoteUtil.isNoteChecked(this.CheckedNoteArray, this.noteItem)
336        } else {
337          NoteUtil.setNoteChecked(this.CheckedNoteArray, this.noteItem)
338          this.refreshFlag = (this.refreshFlag == 0 ? 1 : 0)
339          this.isChecked = NoteUtil.isNoteChecked(this.CheckedNoteArray, this.noteItem)
340        }
341        return;
342      } else {
343        this.selectedNoteData = this.noteItem
344        this.chooseNote = true
345        // save continue data
346        let continueNote: string = JSON.stringify(this.selectedNoteData?.toNoteObject())
347        AppStorage.SetOrCreate<string>('ContinueNote', continueNote)
348        LogUtil.info(TAG, "NoteItemComp, set continue note success")
349      }
350      if (this.portraitModel == false) {
351        this.controllerShow.runJavaScript(
352          "RICH_EDITOR.setHtml('" + this.selectedNoteData?.content_text + "')"
353        )
354        this.controllerShow.runJavaScript(
355          "RICH_EDITOR.cancelSelection()"
356        )
357      }
358      if (this.portraitModel == true) {
359        AppStorage.SetOrCreate<NoteData>('NewNote', this.selectedNoteData)
360        AppStorage.SetOrCreate<FolderData>('NewFolder', this.selectedFolderData)
361        routePage()
362      }
363      this.selectedAll = this.CheckedNoteArray.length ==
364      NoteUtil.getNoteDataArray(AppStorage.Get('AllNoteArray'), this.selectedFolderData.uuid).length
365      this.refreshFlag = (this.refreshFlag == 0 ? 1 : 0)
366    })
367    .gesture(
368    GestureGroup(GestureMode.Exclusive,
369      // 长按:对笔记列表进行操作
370    LongPressGesture()
371      .onAction(() => {
372        if (this.longpress == false) {
373          this.longpress = true
374          NoteUtil.setNoteChecked(this.CheckedNoteArray, this.noteItem)
375          this.isChecked = NoteUtil.isNoteChecked(this.CheckedNoteArray, this.noteItem)
376        }
377      })
378    )
379    )
380
381  }
382}
383
384@Component
385export struct NoteItemListComp {
386  @StorageLink('AllNoteArray') AllNoteArray: NoteData[] = AppStorage.Link('AllNoteArray')
387  @Consume('SelectedFolderData') selectedFolderData: FolderData
388  @Consume('RefreshFlag') refreshFlag: number
389  @Consume('Longpress') longpress: boolean
390  @Consume('Search') search: boolean
391  @Consume @Watch('doSearch') inputKeyword: string
392  @Consume('SearchResultList') searchResultList: NoteData[]
393  @Consume('SelectedNoteData') selectedNoteData: NoteData
394  @Consume('PortraitModel') portraitModel: boolean
395  @State dateList: NoteData[] = []
396  controllerShow: WebviewController
397  @StorageLink('isUpdate') @Watch('updateList') isUpdate: boolean = false
398
399  updateList() {
400    if (this.isUpdate) {
401      this.dateList = NoteUtil.getNoteDataArray(AppStorage.Get('AllNoteArray'), this.selectedFolderData.uuid)
402    }
403    this.isUpdate = false
404    this.doSearch()
405  }
406
407  aboutToAppear() {
408    LogUtil.info(TAG, "inputKeyWord:" + this.inputKeyword)
409    this.inputKeyword = ''
410    this.dateList = NoteUtil.getNoteDataArray(AppStorage.Get('AllNoteArray'), this.selectedFolderData.uuid)
411  }
412
413  doSearch() {
414    if (this.inputKeyword.length == 0) {
415      return
416    }
417    SearchModel.search(NoteUtil.getNoteDataArray(AppStorage.Get('AllNoteArray'), this.selectedFolderData.uuid), this.inputKeyword)
418      .then((result: NoteData[]) => {
419        LogUtil.info(TAG, "result size " + result.length.toString())
420        this.searchResultList = result
421        if (this.searchResultList.length != 0) {
422          this.selectedNoteData = this.searchResultList[0]
423        } else {
424          this.selectedNoteData = NoteUtil.getFirstNoteData(AppStorage.Get('AllNoteArray'), this.selectedFolderData.uuid)
425        }
426        if (this.portraitModel == false) {
427          this.controllerShow.runJavaScript(
428            "RICH_EDITOR.setHtml('" + this.selectedNoteData?.content_text + "')"
429          )
430        }
431        // save continue data
432        let continueNote: string = JSON.stringify(this.selectedNoteData?.toNoteObject())
433        AppStorage.SetOrCreate<string>('ContinueNote', continueNote)
434        LogUtil.info(TAG, "doSearch, set continue note success")
435        this.refreshFlag = (this.refreshFlag == 0 ? 1 : 0)
436      })
437  }
438
439  build() {
440    Column() {
441      Text(this.refreshFlag.toString()).visibility(Visibility.None)
442      Flex() {
443        SearchComp()
444      }
445      .id(this.isUpdate + '')
446      .width("100%")
447      .padding({ left: 24, right: 24, bottom: 12 })
448      .visibility((FolderUtil.getNoteCount(AppStorage.Get('AllNoteArray'), this.selectedFolderData.uuid) == 0) ? Visibility.None : Visibility.Visible)
449
450      Stack() {
451        Flex({ direction: FlexDirection.Column }) {
452          Flex({ justifyContent: FlexAlign.Center }) {
453            Text($r("app.string.permanently_delete_tips"))
454              .fontSize(12)
455              .fontColor($r("app.color.Recently_delete_prompt_font_color"))
456          }
457          .padding({ bottom: this.selectedFolderData.uuid == SysDefFolderUuid.RecentDeletes ? 12 : 0 })
458          .width('100%')
459          .visibility(this.selectedFolderData.uuid == SysDefFolderUuid.RecentDeletes
460                      && FolderUtil.getNoteCount(AppStorage.Get('AllNoteArray'), this.selectedFolderData.uuid) > 0 ? Visibility.Visible : Visibility.None)
461
462          Column() {
463            List({ initialIndex: 0 }) {
464              ListItem() {
465                Column({ space: 8 }) {
466                  Image($r('app.media.emptyPage'))
467                    .width(120)
468                    .height(120)
469                  Text($r("app.string.Empty_page"))
470                    .fontSize(12)
471                    .fontColor($r("app.color.Empty_page_font_color"))
472                }
473              }
474              .id(this.isUpdate + '')
475              .width('100%')
476              .height('100%')
477              .padding({ bottom: 120 })
478              .visibility((FolderUtil.getNoteCount(AppStorage.Get('AllNoteArray'), this.selectedFolderData.uuid) == 0) ? Visibility.Visible : Visibility.None)
479
480              ForEach(this.inputKeyword.length == 0 ?
481              this.dateList : this.searchResultList, (noteItem) => {
482                ListItem() {
483                  Column() {
484                    NoteItemComp({
485                      noteItem: noteItem,
486                      spans: SearchModel.splitToHighlightText(noteItem.title, this.inputKeyword),
487                      controllerShow: this.controllerShow
488                    })
489                  }
490                  .padding({ left: 24, right: 24, bottom: 12 })
491                }
492                .visibility((FolderUtil.getNoteCount(AppStorage.Get('AllNoteArray'), this.selectedFolderData.uuid) == 0) ? Visibility.None : Visibility.Visible)
493              }, noteItem => JSON.stringify(noteItem))
494            }
495            .id(this.isUpdate + '')
496            .margin((FolderUtil.getNoteCount(AppStorage.Get('AllNoteArray'), this.selectedFolderData.uuid) == 0) ? {
497                                                                                                                     bottom: 0
498                                                                                                                   } : {
499                                                                                                                         bottom: 56
500                                                                                                                       })
501            .layoutWeight(1)
502            .listDirection(Axis.Vertical)
503            .edgeEffect(EdgeEffect.Spring)
504          }
505          .layoutWeight(1)
506          .height("100%")
507          .margin({ top: this.search ? 8 : 0 })
508        }
509        .height("100%")
510        .width("100%")
511
512        // search input mask
513        Column() {
514        }
515        .height("100%")
516        .width("100%")
517        .backgroundColor("#18181A")
518        .opacity(0.1)
519        .visibility(this.search ? Visibility.Visible : Visibility.Hidden)
520      }
521    }
522    .onClick(() => {
523      this.search = false
524      inputMethod.getController().stopInputSession()
525      AppStorage.SetOrCreate<boolean>('Search', this.search)
526    })
527  }
528}
529
530@Component
531export struct OperateNoteComp {
532  @Consume('Longpress') longpress: boolean
533  @StorageLink('CheckedNoteArray') CheckedNoteArray: NoteData[] = []
534  @StorageLink('AllNoteArray') AllNoteArray: NoteData[] = AppStorage.Link('AllNoteArray')
535  @Consume('SelectedFolderData') selectedFolderData: FolderData
536  @Consume('RefreshFlag') refreshFlag: number
537  @Consume('SelectedNoteData') selectedNoteData: NoteData
538  @Consume('PortraitModel') portraitModel: boolean
539  @Consume('selectedAll') selectedAll: boolean
540  @StorageLink('isUpdate') isUpdate: boolean = false
541  controllerShow: WebviewController
542  noteDataMoveDialogCtl: CustomDialogController = new CustomDialogController({
543    builder: NoteDataMoveDialog({ onConfirm: this.onMoveConfirm.bind(this) }),
544    alignment: DialogAlignment.Center,
545    autoCancel: false,
546    customStyle: true,
547  })
548
549  aboutToDisappear() {
550    this.noteDataMoveDialogCtl = null
551    this.noteDataDeleteDialogCtl = null
552  }
553
554  onMoveConfirm(folderUuid: string) {
555    this.CheckedNoteArray.forEach((noteItem) => {
556      noteItem.folder_uuid = folderUuid
557      // update note to db
558      let predicates_note = RdbStoreUtil.getRdbPredicates(TableName.NoteTable)
559      predicates_note.equalTo(NoteTableColumn.Uuid, noteItem.uuid)
560      RdbStoreUtil.update(noteItem.toNoteObject(), predicates_note, null)
561    })
562    this.selectedNoteData = NoteUtil.getFirstNoteData(this.AllNoteArray, this.selectedFolderData.uuid)
563    // save continue data
564    let continueNote: string = JSON.stringify(this.selectedNoteData?.toNoteObject())
565    AppStorage.SetOrCreate<string>('ContinueNote', continueNote)
566    LogUtil.info(TAG, "onMoveConfirm, set continue note success")
567    if (this.portraitModel == false) {
568      this.controllerShow.runJavaScript("RICH_EDITOR.setHtml('" + this.selectedNoteData?.content_text + "')")
569    }
570    this.longpress = false
571    this.refreshFlag = (this.refreshFlag == 0 ? 1 : 0)
572    NoteUtil.unsetAllNotesChecked(this.CheckedNoteArray)
573    NoteUtil.refreshAll()
574  }
575
576  noteDataDeleteDialogCtl: CustomDialogController = new CustomDialogController({
577    builder: DeleteDialog({ onConfirm: this.onDeleteConfirm.bind(this), multiSelect: true }),
578    alignment: DialogAlignment.Center,
579    autoCancel: false,
580    customStyle: true,
581  })
582
583  onDeleteConfirm() {
584    if (this.selectedFolderData.uuid != SysDefFolderUuid.RecentDeletes) {
585      this.CheckedNoteArray.forEach((noteItem: NoteData) => {
586        noteItem.is_deleted = Delete.Yes
587        noteItem.deleted_time = new Date().getTime()
588        // update note to db
589        let predicates_note = RdbStoreUtil.getRdbPredicates(TableName.NoteTable)
590        predicates_note.equalTo(NoteTableColumn.Uuid, noteItem.uuid)
591        RdbStoreUtil.update(noteItem.toNoteObject(), predicates_note, null)
592      })
593    } else {
594      this.CheckedNoteArray.forEach((noteItem: NoteData) => {
595        NoteUtil.removeNoteData(this.AllNoteArray, noteItem.uuid)
596        // delete note from db
597        let predicates_note = RdbStoreUtil.getRdbPredicates(TableName.NoteTable)
598        predicates_note.equalTo(NoteTableColumn.Uuid, noteItem.uuid)
599        RdbStoreUtil.delete(predicates_note, null)
600      })
601    }
602    NoteUtil.unsetAllNotesChecked(this.CheckedNoteArray)
603    this.refreshFlag = (this.refreshFlag == 0 ? 1 : 0)
604    this.longpress = false
605    this.selectedNoteData = NoteUtil.getFirstNoteData(AppStorage.Get('AllNoteArray'), this.selectedFolderData.uuid)
606    if (this.portraitModel == false) {
607      this.controllerShow.runJavaScript("RICH_EDITOR.setHtml('" + this.selectedNoteData?.content_text + "')")
608    }
609    // save continue data
610    let continueNote: string = JSON.stringify(this.selectedNoteData?.toNoteObject())
611    AppStorage.SetOrCreate<string>('ContinueNote', continueNote)
612    LogUtil.info(TAG, "OperateNoteComp, set continue note success")
613    NoteUtil.refreshAll()
614  }
615
616  build() {
617    Row() {
618      Image($r('app.media.set_top'))
619        .width(24)
620        .height(24)
621        .opacity(this.CheckedNoteArray.length == 0 ? 0.4 : 1)
622        .enabled(this.CheckedNoteArray.length == 0 ? false : true)
623        .margin({ right: this.selectedFolderData.uuid == SysDefFolderUuid.RecentDeletes ? 0 : 18 })
624        .visibility(this.selectedFolderData.uuid == SysDefFolderUuid.RecentDeletes ? Visibility.None : Visibility.Visible)
625        .onClick(() => {
626          this.CheckedNoteArray.forEach((noteItem) => {
627            noteItem.is_top = (noteItem.is_top == Top.Yes) ? Top.No : Top.Yes
628            // update note to db
629            let predicates_note = RdbStoreUtil.getRdbPredicates(TableName.NoteTable)
630            predicates_note.equalTo(NoteTableColumn.Uuid, noteItem.uuid)
631            RdbStoreUtil.update(noteItem.toNoteObject(), predicates_note, null)
632          })
633          this.longpress = false
634          NoteUtil.unsetAllNotesChecked(this.CheckedNoteArray)
635          NoteUtil.refreshAll()
636        })
637      Image($r('app.media.move'))
638        .width(24)
639        .height(24)
640        .opacity(this.CheckedNoteArray.length == 0 ? 0.4 : 1)
641        .enabled(this.CheckedNoteArray.length == 0 ? false : true)
642        .margin({ right: this.selectedFolderData.uuid == SysDefFolderUuid.RecentDeletes ? 0 : 18 })
643        .visibility(this.selectedFolderData.uuid == SysDefFolderUuid.RecentDeletes ? Visibility.None : Visibility.Visible)
644        .onClick(() => {
645          this.noteDataMoveDialogCtl.open()
646        })
647      Image($r('app.media.delete'))
648        .width(24)
649        .height(24)
650        .margin({ right: 18 })
651        .opacity(this.CheckedNoteArray.length == 0 ? 0.4 : 1)
652        .enabled(this.CheckedNoteArray.length == 0 ? false : true)
653        .onClick(() => {
654          this.noteDataDeleteDialogCtl.open()
655        })
656      Image($r('app.media.recover'))
657        .width(24)
658        .height(24)
659        .opacity(this.CheckedNoteArray.length == 0 ? 0.4 : 1)
660        .enabled(this.CheckedNoteArray.length == 0 ? false : true)
661        .margin({ right: this.selectedFolderData.uuid == SysDefFolderUuid.RecentDeletes ? 18 : 0 })
662        .visibility(this.selectedFolderData.uuid == SysDefFolderUuid.RecentDeletes ? Visibility.Visible : Visibility.None)
663        .onClick(() => {
664          this.CheckedNoteArray.forEach((noteItem) => {
665            noteItem.is_deleted = Delete.No
666            noteItem.deleted_time = 0
667            let context: any = getContext(this)
668            let resource = {
669              bundleName: "com.ohos.note",
670              moduleName: "default",
671              id: $r('app.string.restore').id
672            };
673            context.resourceManager.getString(resource, (error, value) => {
674              if (error != null) {
675                console.log("error is " + error);
676              } else {
677                prompt.showToast({ message: value, duration: 2000 });
678              }
679            });
680            // update note to db
681            let predicates_note = RdbStoreUtil.getRdbPredicates(TableName.NoteTable)
682            predicates_note.equalTo(NoteTableColumn.Uuid, noteItem.uuid)
683            RdbStoreUtil.update(noteItem.toNoteObject(), predicates_note, null)
684          })
685          this.longpress = false
686          NoteUtil.unsetAllNotesChecked(this.CheckedNoteArray)
687          NoteUtil.refreshAll()
688        })
689      Image(this.CheckedNoteArray.length == NoteUtil.getNoteDataArray(AppStorage.Get('AllNoteArray'), this.selectedFolderData.uuid)
690        .length ? $r('app.media.check_all1') : $r('app.media.check_all'))
691        .width(24)
692        .height(24)
693        .id(this.isUpdate + '')
694        .onClick(() => {
695          LogUtil.info(TAG, "select all click")
696          if (this.CheckedNoteArray.length <
697          NoteUtil.getNoteDataArray(AppStorage.Get('AllNoteArray'), this.selectedFolderData.uuid).length) {
698            NoteUtil.setAllNotesChecked(this.CheckedNoteArray, NoteUtil.getNoteDataArray(AppStorage.Get('AllNoteArray'), this.selectedFolderData.uuid))
699          } else {
700            NoteUtil.unsetAllNotesChecked(this.CheckedNoteArray)
701          }
702          this.selectedAll = !this.selectedAll
703          this.refreshFlag = (this.refreshFlag == 0 ? 1 : 0)
704          NoteUtil.refreshAll()
705        })
706    }
707    .width(this.selectedFolderData.uuid == SysDefFolderUuid.RecentDeletes ? 168 : 248)
708    .visibility(this.longpress && this.portraitModel == false ? Visibility.Visible : Visibility.None)
709  }
710}
711
712@Component
713export struct AddNoteComp {
714  @StorageLink('AllNoteArray') AllNoteArray: NoteData[] = AppStorage.Link('AllNoteArray')
715  @Consume('Longpress') longpress: boolean
716  @Consume('SelectedFolderData') selectedFolderData: FolderData
717  @Consume('SelectedNoteData') selectedNoteData: NoteData
718  @Consume('SectionStatus') sectionStatus: number
719  @Consume('LastSectionStatus') lastSectionStatus: number
720  @Consume('EditModel') editModel: boolean
721  @Consume('ChooseNote') chooseNote: boolean
722  @Consume('PortraitModel') portraitModel: boolean
723  controllerShow: WebviewController
724
725  build() {
726    Image($r('app.media.addNote'))
727      .width(24)
728      .height(24)
729      .margin({ right: 12 })
730      .responseRegion({ x: -15.0, y: -15.0, width: 54, height: 54 })
731      .onClick(() => {
732        let noteData
733        if (this.selectedFolderData.uuid == SysDefFolderUuid.AllNotes || this.selectedFolderData.uuid == SysDefFolderUuid.MyFavorites) {
734          noteData = new NoteData(0, "标题", new Date().getTime() + "", SysDefFolderUuid.UnClassified, "", "", NoteType.SysDef, Top.No, Favorite.No, Delete.No, new Date().getTime(), new Date().getTime(), 0, 0)
735        } else {
736          noteData = new NoteData(0, "标题", new Date().getTime() + "", this.selectedFolderData.uuid, "", "", NoteType.SysDef, Top.No, Favorite.No, Delete.No, new Date().getTime(), new Date().getTime(), 0, 0)
737        }
738
739        this.AllNoteArray.push(noteData)
740        RdbStoreUtil.insert(TableName.NoteTable, noteData.toNoteObject(), null)
741        LogUtil.info(TAG, 'insert new note is:' + noteData.uuid)
742
743        this.selectedNoteData = noteData
744        AppStorage.SetOrCreate<NoteData>('NewNote', noteData)
745        if (this.portraitModel == false) {
746          this.controllerShow.runJavaScript(
747            "RICH_EDITOR.setHtml('" + this.selectedNoteData?.content_text + "')"
748          )
749        }
750        if (this.portraitModel == true) {
751          this.editModel = true
752        }
753        this.chooseNote = true
754        // save continue data
755        let continueNote: string = JSON.stringify(this.selectedNoteData?.toNoteObject())
756        AppStorage.SetOrCreate<FolderData>('NewFolder', this.selectedFolderData)
757        AppStorage.SetOrCreate<string>('ContinueNote', continueNote)
758        LogUtil.info(TAG, "addNote, set continue note success")
759        routePage()
760        AppStorage.SetOrCreate('isUpdate', true)
761      })
762      .visibility(this.longpress || this.selectedFolderData.uuid == SysDefFolderUuid.RecentDeletes ? Visibility.None : Visibility.Visible)
763  }
764}
765
766@Component
767export struct SearchComp {
768  @Consume('Search') search: boolean
769  @Consume('InputKeyword') inputKeyword: string
770  @Consume('Longpress') longpress: boolean
771  @State text: string = ''
772  @StorageLink('isFocusOnSearch') isFocusOnSearch: boolean = true
773
774  build() {
775    Row() {
776      Image($r('app.media.back'))
777        .width(24)
778        .height(24)
779        .responseRegion({ x: -15.0, y: -15.0, width: 54, height: 54 })
780        .margin({ right: this.search ? 16 : 0 })
781        .visibility(this.search ? Visibility.Visible : Visibility.None)
782        .onClick(() => {
783          focusControl.requestFocus('searchFocus')
784          this.search = false
785          // 退出键盘
786          // @ts-ignore
787          inputMethod.getController().stopInputSession();
788          AppStorage.SetOrCreate<boolean>('Search', this.search)
789        })
790
791      Flex({ justifyContent: FlexAlign.Start }) {
792        Image($r('app.media.search'))
793          .width(20)
794          .height(20)
795          .focusable(true)
796          .key('searchFocus')
797          .defaultFocus(true)
798        TextInput({ placeholder: $r('app.string.searchNote'), text: this.text })
799          .backgroundColor(this.longpress ? $r("app.color.search_longpress_bgcolor_f7f8f9") : $r("app.color.color_ffffff"))
800          .caretColor($r("app.color.search_note_caret_color"))
801          .enabled(this.longpress ? false : true)
802          .padding({ left: 6, top: 1 })
803          .onEditChange((isEditing: boolean) => {
804            //            this.search = isEditing
805          })
806          .onChange((value: string) => {
807            if (!this.longpress) {
808              LogUtil.info(TAG, "Search value: " + value)
809              this.text = value
810              this.inputKeyword = value
811            }
812          })
813          .onClick(() => {
814            if (this.longpress) {
815              this.search = false
816              AppStorage.SetOrCreate<boolean>('Search', this.search)
817            } else {
818              this.search = true
819              AppStorage.SetOrCreate<boolean>('Search', this.search)
820            }
821          })
822            // whether the focus is on the search input before coutinue
823          .onFocus(() => {
824            this.isFocusOnSearch = true
825          })
826          .onBlur(() => {
827            this.isFocusOnSearch = false
828          })
829            // key for request focus after coutinue
830          .key('searchInput')
831          .restoreId(3)
832      }
833      .backgroundColor(this.longpress ? $r("app.color.search_longpress_bgcolor_f7f8f9") : $r("app.color.color_ffffff"))
834      .height(40)
835      .opacity(this.longpress ? 0.4 : 1)
836      .padding({ left: 6, right: 12, top: 9, bottom: 9 })
837      .borderRadius(20)
838      .border({ width: 1.5, color: $r("app.color.divider_color_e4e4e4") })
839      .margin({ right: this.search ? 40 : 0 })
840    }
841  }
842}
843
844@Component
845export struct OperateNoteCompForPortrait {
846  @Consume('Longpress') longpress: boolean
847  @StorageLink('CheckedNoteArray') CheckedNoteArray: NoteData[] = []
848  @StorageLink('AllNoteArray') AllNoteArray: NoteData[] = AppStorage.Link('AllNoteArray')
849  @Consume('SelectedFolderData') selectedFolderData: FolderData
850  @Consume('RefreshFlag') @Watch('opacityChange') refreshFlag: number
851  @Consume('SelectedNoteData') selectedNoteData: NoteData
852  @Consume('PortraitModel') portraitModel: boolean
853  @State greyOpacity: boolean = false
854  @StorageLink('isUpdate') isUpdate: boolean = false
855  noteDataMoveDialogCtlBottom: CustomDialogController = new CustomDialogController({
856    builder: NoteDataMoveDialog({ onConfirm: this.onMoveConfirm.bind(this) }),
857    alignment: DialogAlignment.Bottom,
858    autoCancel: false,
859    customStyle: true,
860  })
861
862  aboutToDisappear() {
863    this.noteDataMoveDialogCtlBottom = null
864    this.noteDataDeleteDialogCtlBottom = null
865  }
866
867  opacityChange() {
868    if (this.CheckedNoteArray.length == 0 && this.longpress == true) {
869      this.greyOpacity = true
870      LogUtil.info(TAG, "none checked array")
871    } else {
872      this.greyOpacity = false
873      LogUtil.info(TAG, this.CheckedNoteArray.length.toString())
874    }
875  }
876
877  onMoveConfirm(folderUuid: string) {
878    this.CheckedNoteArray.forEach((noteItem) => {
879      noteItem.folder_uuid = folderUuid
880      // update note to db
881      let predicates_note = RdbStoreUtil.getRdbPredicates(TableName.NoteTable)
882      predicates_note.equalTo(NoteTableColumn.Uuid, noteItem.uuid)
883      RdbStoreUtil.update(noteItem.toNoteObject(), predicates_note, null)
884    })
885    this.selectedNoteData = NoteUtil.getFirstNoteData(this.AllNoteArray, this.selectedFolderData.uuid)
886    // save continue data
887    let continueNote: string = JSON.stringify(this.selectedNoteData?.toNoteObject())
888    AppStorage.SetOrCreate<string>('ContinueNote', continueNote)
889    LogUtil.info(TAG, "onMoveConfirm, set continue note success")
890    this.longpress = false
891    this.refreshFlag = (this.refreshFlag == 0 ? 1 : 0)
892    NoteUtil.unsetAllNotesChecked(this.CheckedNoteArray)
893    NoteUtil.refreshAll()
894  }
895
896  noteDataDeleteDialogCtlBottom: CustomDialogController = new CustomDialogController({
897    builder: DeleteDialog({ onConfirm: this.onDeleteConfirm.bind(this), multiSelect: true }),
898    alignment: DialogAlignment.Bottom,
899    autoCancel: false,
900    customStyle: true,
901  })
902
903  onDeleteConfirm() {
904    if (this.selectedFolderData.uuid != SysDefFolderUuid.RecentDeletes) {
905      this.CheckedNoteArray.forEach((noteItem: NoteData) => {
906        noteItem.is_deleted = Delete.Yes
907        noteItem.deleted_time = new Date().getTime()
908        // update note to db
909        let predicates_note = RdbStoreUtil.getRdbPredicates(TableName.NoteTable)
910        predicates_note.equalTo(NoteTableColumn.Uuid, noteItem.uuid)
911        RdbStoreUtil.update(noteItem.toNoteObject(), predicates_note, null)
912      })
913    } else {
914      this.CheckedNoteArray.forEach((noteItem: NoteData) => {
915        NoteUtil.removeNoteData(this.AllNoteArray, noteItem.uuid)
916        // delete note from db
917        let predicates_note = RdbStoreUtil.getRdbPredicates(TableName.NoteTable)
918        predicates_note.equalTo(NoteTableColumn.Uuid, noteItem.uuid)
919        RdbStoreUtil.delete(predicates_note, null)
920      })
921    }
922    NoteUtil.unsetAllNotesChecked(this.CheckedNoteArray)
923    this.longpress = false
924    this.refreshFlag = (this.refreshFlag == 0 ? 1 : 0)
925    this.selectedNoteData = NoteUtil.getFirstNoteData(AppStorage.Get('AllNoteArray'), this.selectedFolderData.uuid)
926    // save continue data
927    let continueNote: string = JSON.stringify(this.selectedNoteData?.toNoteObject())
928    AppStorage.SetOrCreate<string>('ContinueNote', continueNote)
929    LogUtil.info(TAG, "OperateNoteCompForPortrait, set continue note success")
930    NoteUtil.refreshAll()
931  }
932
933  build() {
934    Row() {
935      if (this.selectedFolderData.uuid != SysDefFolderUuid.RecentDeletes) {
936        Column() {
937          Image($r("app.media.set_top"))
938            .opacity(this.greyOpacity ? 0.4 : 1)
939            .width(24)
940            .height(24)
941            .responseRegion({ x: -15.0, y: -15.0, width: 54, height: 54 })
942            .onClick(() => {
943              this.CheckedNoteArray.forEach((noteItem) => {
944                noteItem.is_top = (noteItem.is_top == Top.Yes) ? Top.No : Top.Yes
945                // update note to db
946                let predicates_note = RdbStoreUtil.getRdbPredicates(TableName.NoteTable)
947                predicates_note.equalTo(NoteTableColumn.Uuid, noteItem.uuid)
948                RdbStoreUtil.update(noteItem.toNoteObject(), predicates_note, null)
949              })
950              this.longpress = false
951              this.refreshFlag = (this.refreshFlag == 0 ? 1 : 0)
952              NoteUtil.unsetAllNotesChecked(this.CheckedNoteArray)
953              NoteUtil.refreshAll()
954            })
955          Text($r("app.string.set_top"))
956            .opacity(this.greyOpacity ? 0.4 : 1)
957            .fontSize(10)
958            .fontColor($r("app.color.set_top_font_color"))
959            .padding({ top: 5 })
960        }
961        .width("25%")
962        .height("100%")
963        .opacity(this.greyOpacity ? 0.4 : 1)
964        .enabled(this.greyOpacity ? false : true)
965        .alignItems(HorizontalAlign.Center)
966        .justifyContent(FlexAlign.Center)
967      }
968
969      Column() {
970        Image($r('app.media.delete'))
971          .opacity(this.greyOpacity ? 0.4 : 1)
972          .width(24)
973          .height(24)
974          .responseRegion({ x: -15.0, y: -15.0, width: 54, height: 54 })
975          .onClick(() => {
976            this.noteDataDeleteDialogCtlBottom.open()
977            AppStorage.SetOrCreate('isUpdate', true)
978          })
979        Text($r("app.string.delete"))
980          .opacity(this.greyOpacity ? 0.4 : 1)
981          .fontSize(10)
982          .fontColor($r("app.color.delete_font_color"))
983          .padding({ top: 5 })
984      }
985      .width(this.selectedFolderData.uuid == SysDefFolderUuid.RecentDeletes ? 120 : "25%")
986      .height("100%")
987      .opacity(this.greyOpacity ? 0.4 : 1)
988      .enabled(this.greyOpacity ? false : true)
989      .alignItems(HorizontalAlign.Center)
990      .justifyContent(FlexAlign.Center)
991
992      if (this.selectedFolderData.uuid != SysDefFolderUuid.RecentDeletes) {
993        Column() {
994          Image($r('app.media.move'))
995            .opacity(this.greyOpacity ? 0.4 : 1)
996            .width(24)
997            .height(24)
998            .responseRegion({ x: -15.0, y: -15.0, width: 54, height: 54 })
999            .onClick(() => {
1000              this.noteDataMoveDialogCtlBottom.open()
1001              AppStorage.SetOrCreate('isUpdate', true)
1002            })
1003          Text($r("app.string.move"))
1004            .opacity(this.greyOpacity ? 0.4 : 1)
1005            .fontSize(10)
1006            .fontColor($r("app.color.move_font_color"))
1007            .padding({ top: 5 })
1008        }
1009        .width("25%")
1010        .height("100%")
1011        .opacity(this.greyOpacity ? 0.4 : 1)
1012        .enabled(this.greyOpacity ? false : true)
1013        .alignItems(HorizontalAlign.Center)
1014        .justifyContent(FlexAlign.Center)
1015      }
1016
1017
1018      if (this.selectedFolderData.uuid == SysDefFolderUuid.RecentDeletes) {
1019        Column() {
1020          Image($r('app.media.recover'))
1021            .width(24)
1022            .height(24)
1023            .responseRegion({ x: -15.0, y: -15.0, width: 54, height: 54 })
1024            .onClick(() => {
1025              this.CheckedNoteArray.forEach((noteItem) => {
1026                noteItem.is_deleted = Delete.No
1027                noteItem.deleted_time = 0
1028                let context: any = getContext(this)
1029                let resource = {
1030                  bundleName: "com.ohos.note",
1031                  moduleName: "default",
1032                  id: $r('app.string.restore').id
1033                };
1034                context.resourceManager.getString(resource, (error, value) => {
1035                  if (error != null) {
1036                    console.log("error is " + error);
1037                  } else {
1038                    prompt.showToast({ message: value, duration: 2000 });
1039                  }
1040                });
1041                // update note to db
1042                let predicates_note = RdbStoreUtil.getRdbPredicates(TableName.NoteTable)
1043                predicates_note.equalTo(NoteTableColumn.Uuid, noteItem.uuid)
1044                RdbStoreUtil.update(noteItem.toNoteObject(), predicates_note, null)
1045              })
1046              this.longpress = false
1047              NoteUtil.unsetAllNotesChecked(this.CheckedNoteArray)
1048              this.refreshFlag = (this.refreshFlag == 0 ? 1 : 0)
1049              AppStorage.SetOrCreate('isUpdate', true)
1050              NoteUtil.refreshAll()
1051            })
1052          Text($r("app.string.recover"))
1053            .fontSize(10)
1054            .fontColor($r("app.color.recover_font_color"))
1055            .padding({ top: 5 })
1056        }
1057        .width(this.selectedFolderData.uuid == SysDefFolderUuid.RecentDeletes ? 120 : "25%")
1058        .height("100%")
1059        .opacity(this.greyOpacity ? 0.4 : 1)
1060        .enabled(this.greyOpacity ? false : true)
1061        .alignItems(HorizontalAlign.Center)
1062        .justifyContent(FlexAlign.Center)
1063      }
1064
1065      Column() {
1066        Image($r('app.media.check_all'))
1067          .width(24)
1068          .height(24)
1069          .responseRegion({ x: -15.0, y: -15.0, width: 54, height: 54 })
1070          .id(this.isUpdate + '')
1071          .onClick(() => {
1072            if (this.CheckedNoteArray.length <
1073            NoteUtil.getNoteDataArray(AppStorage.Get('AllNoteArray'), this.selectedFolderData.uuid)
1074              .length) {
1075              NoteUtil.setAllNotesChecked(this.CheckedNoteArray, NoteUtil.getNoteDataArray(AppStorage.Get('AllNoteArray'), this.selectedFolderData.uuid))
1076            } else {
1077              NoteUtil.unsetAllNotesChecked(this.CheckedNoteArray)
1078            }
1079            this.refreshFlag = (this.refreshFlag == 0 ? 1 : 0)
1080            NoteUtil.refreshAll()
1081          })
1082        Text($r("app.string.check_all"))
1083          .fontSize(10)
1084          .fontColor($r("app.color.check_all_font_color"))
1085          .padding({ top: 5 })
1086      }
1087      .width(this.selectedFolderData.uuid == SysDefFolderUuid.RecentDeletes ? 120 : "25%")
1088      .height("100%")
1089      .alignItems(HorizontalAlign.Center)
1090      .justifyContent(FlexAlign.Center)
1091    }
1092    .justifyContent(FlexAlign.Center)
1093    .width("100%")
1094    .height(56)
1095    .visibility(this.longpress && this.portraitModel == true ? Visibility.Visible : Visibility.None)
1096  }
1097}
1098