• 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 RdbStoreUtil from '@ohos/utils/src/main/ets/default/baseUtil/RdbStoreUtil'
18import FolderData from '@ohos/utils/src/main/ets/default/model/databaseModel/FolderData'
19import NoteData from '@ohos/utils/src/main/ets/default/model/databaseModel/NoteData'
20import util from '@ohos.util'
21import {
22  TableName,
23  NoteTableColumn,
24  SysDefFolderUuid,
25  Favorite,
26  Delete
27} from '@ohos/utils/src/main/ets/default/model/databaseModel/EnumData'
28import StyleConstants from '@ohos/utils/src/main/ets/default/constants/StyleConstants'
29import { EditContentDialogPortrait, DeleteDialog, EditTitleDialog } from './CusDialogComp'
30import FolderUtil from '@ohos/utils/src/main/ets/default/baseUtil/FolderUtil'
31import NoteUtil from '@ohos/utils/src/main/ets/default/baseUtil/NoteUtil'
32import prompt from '@system.prompt'
33import { LogUtil } from '@ohos/utils/src/main/ets/default/baseUtil/LogUtil'
34import OperationUtils from '@ohos/utils/src/main/ets/default/baseUtil/OperationUtils'
35import router from '@system.router'
36import inputMethod from '@ohos.inputMethod';
37import { folderTextMap } from '@ohos/utils/src/main/ets/default/model/NoteBaseData'
38import abilityAccessCtrl from '@ohos.abilityAccessCtrl';
39
40var time_id: number
41
42const TAG = "NoteContentCompPortrait"
43
44async function routePage() {
45  try {
46    await router.back()
47  } catch (err) {
48    LogUtil.info(TAG, "fail callback")
49  }
50}
51
52// Note content component
53@Component
54export struct NoteContentCompPortrait {
55  @Provide('SelectedNoteData') selectedNoteData: NoteData = AppStorage.Get('NewNote')
56  @Provide('SelectedFolderData') selectedFolderData: FolderData = AppStorage.Get("NewFolder")
57  @StorageLink('AllNoteArray') AllNoteArray: NoteData[] = AppStorage.Link('AllNoteArray')
58  @Provide('EditModel') editModel: boolean = false
59  @StorageLink('dpi') dpi: number = 240
60  controllerShow: WebviewController
61  private editContentFlag = false
62  @StorageLink('ScrollTopPercent') scrollTopPercent: number = 0.0
63  editContentDialogCtl: CustomDialogController = new CustomDialogController({
64    builder: EditContentDialogPortrait({ confirm: this.confirm.bind(this) }),
65    alignment: DialogAlignment.Bottom,
66    autoCancel: true,
67    customStyle: true,
68  })
69
70  confirm(excuteJs: string) {
71    this.controllerShow.runJavaScript(excuteJs)
72  }
73
74  storeScrollTop(scrollTop: number) {
75    if (scrollTop < 0) {
76      return
77    }
78    AppStorage.SetOrCreate<number>('ScrollTopPercent', scrollTop / this.controllerShow.getPageHeight())
79  }
80
81  restoreScrollTop() {
82    try {
83      if (!AppStorage.Has('remoteScrollTopPercent')) {
84        return
85      }
86      var scrollTopPercent = AppStorage.Get<number>('remoteScrollTopPercent')
87      if (scrollTopPercent < 0) {
88        return
89      }
90      this.controllerShow.runJavaScript(
91        'document.documentElement.scrollTop = ' + this.controllerShow.getPageHeight() * scrollTopPercent
92      )
93    } catch (error) {
94      LogUtil.info(TAG, 'restoreScrollTop error')
95    }
96
97  }
98
99  restoreFocus() {
100    if (!AppStorage.Has('isRemoteFocusOnSearch')) {
101      return
102    }
103    let isRemoteFocusOnSearch = AppStorage.Get<boolean>('isRemoteFocusOnSearch')
104    if (isRemoteFocusOnSearch) {
105      focusControl.requestFocus('searchInput')
106    }
107    AppStorage.Delete('isRemoteFocusOnSearch')
108  }
109
110  noteContent = {
111    callbackhtml: (html) => {
112      LogUtil.info(TAG, 'note uuid is:' + this.selectedNoteData.uuid)
113      this.selectedNoteData.content_text = html
114      this.selectedNoteData.modified_time = new Date().getTime()
115      let predicates_note = RdbStoreUtil.getRdbPredicates(TableName.NoteTable)
116      predicates_note.equalTo(NoteTableColumn.Uuid, this.selectedNoteData.uuid)
117      RdbStoreUtil.update(this.selectedNoteData.toNoteObject(), predicates_note, null)
118      LogUtil.info(TAG, 'update note success:' + this.selectedNoteData.uuid)
119      // save continue data
120      let continueNote: string = JSON.stringify(this.selectedNoteData.toNoteObject())
121      AppStorage.SetOrCreate<string>('ContinueNote', continueNote)
122      LogUtil.info(TAG, "callbackhtml, set continue note success")
123    },
124    callbackImagePath: (imgName) => {
125      // updata note image
126      LogUtil.info(TAG, 'note imgName is:' + imgName)
127      this.selectedNoteData.content_img = imgName
128    },
129
130    callbackScheduledSave: (html) => {
131      LogUtil.info(TAG, 'callbackScheduledSave')
132      if (this.selectedNoteData.content_text == html) {
133        LogUtil.info(TAG, 'callbackScheduledSave the same value return')
134        return;
135      }
136      this.selectedNoteData.content_text = html
137      this.selectedNoteData.modified_time = new Date().getTime()
138      let predicates_note = RdbStoreUtil.getRdbPredicates(TableName.NoteTable)
139      predicates_note.equalTo(NoteTableColumn.Uuid, this.selectedNoteData.uuid)
140      RdbStoreUtil.update(this.selectedNoteData.toNoteObject(), predicates_note, null)
141      LogUtil.info(TAG, 'callbackScheduledSave, update note success:' + this.selectedNoteData.uuid)
142      // save continue data
143      let continueNote: string = JSON.stringify(this.selectedNoteData.toNoteObject())
144      AppStorage.SetOrCreate<string>('ContinueNote', continueNote)
145      LogUtil.info(TAG, 'callbackScheduledSave, set continue note success')
146    },
147    callbackPasteImage: (html) => {
148      if (html) {
149        LogUtil.info(TAG, 'paste info' + html)
150        let realHtml = ""
151        let base64regex = /^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/
152        if (html && html.indexOf("base64") > 0) {
153          LogUtil.info(TAG, " getSrcFromHtml, src[1] : " + html)
154          let imgData = html.split(',')[1];
155          let imgType = 'png'
156          if (html.indexOf("jpeg") > 0) {
157            imgType = 'jpg'
158          } else if (html.indexOf("gif") > 0) {
159            imgType = 'gif'
160          }
161          let filePath = ""
162          if (base64regex.test(imgData)) {
163            let base64 = new util.Base64()
164            let decodeArr = base64.decodeSync(imgData)
165            filePath = OperationUtils.saveImageData(decodeArr, imgType)
166          } else {
167            filePath = OperationUtils.saveImage(imgData, imgType)
168          }
169          realHtml = "file://" + filePath
170        }
171        LogUtil.info(TAG, 'paste info11' + realHtml)
172        this.controllerShow.runJavaScript("javascript:RICH_EDITOR.insertImageHtml('" + realHtml + "')")
173      } else {
174        LogUtil.info(TAG, 'paste info22224')
175      }
176    },
177    callbackGetSize: (fontSize) => {
178      if (fontSize === 16) {
179        this.selectedNoteData.slider_value = 0
180      } else if (fontSize === 18) {
181        this.selectedNoteData.slider_value = 4
182      } else if (fontSize === 24) {
183        this.selectedNoteData.slider_value = 8
184      } else if (fontSize === 32) {
185        this.selectedNoteData.slider_value = 12
186      } else if (fontSize === 48) {
187        this.selectedNoteData.slider_value = 16
188      }
189    },
190    addToDo: () => {
191      // 清单
192      this.controllerShow.runJavaScript("javascript:RICH_EDITOR.setTodo()")
193    },
194    chooseStyle: () => {
195      this.editContentDialogCtl.open()
196    },
197    openAlbum: async () => {
198      let permissionList: Array<string> = [
199        "ohos.permission.READ_MEDIA",
200        "ohos.permission.WRITE_MEDIA",
201      ]
202      let context: any = getContext(this);
203      let AtManager = abilityAccessCtrl.createAtManager();
204      // @ts-ignore
205      await AtManager.requestPermissionsFromUser(context, permissionList).then((data) => {
206        LogUtil.info(TAG, 'data permissions : ' + data.permissions)
207        LogUtil.info(TAG, 'data result: ' + data.authResults)
208        let sum = 0
209        for (let i = 0; i < data.authResults.length; i++) {
210          sum += data.authResults[i]
211        }
212        LogUtil.info(TAG, 'request permissions sum: ' + sum)
213      }).catch((err) => {
214        LogUtil.warn(TAG, 'failed to requestPermissionsFromUser : ' + err.code);
215      })
216      LogUtil.info(TAG, 'startAbility start')
217      await globalThis.noteContext.startAbilityForResult({
218        parameters: { uri: "singleselect" },
219        bundleName: "com.ohos.photos",
220        abilityName: "com.ohos.photos.MainAbility",
221      }).then(v => {
222        let want = v['want'];
223        if (want != null && want != undefined) {
224          let param = want['parameters'];
225          let imageUri = ""
226          if (param != null && param != undefined) {
227            let uri = param['select-item-list'];
228            imageUri = uri[0];
229          }
230          LogUtil.info(TAG, "image url" + imageUri)
231          // 拷贝
232          if (imageUri != null && imageUri != "") {
233            OperationUtils.copy(imageUri).then((uriPath) => {
234              var path = "file://" + uriPath
235              LogUtil.info(TAG, 'image uri is:' + path)
236              this.controllerShow.runJavaScript("javascript:RICH_EDITOR.getFocus()")
237              this.controllerShow.runJavaScript("javascript:RICH_EDITOR.insertImage('" + path + "')")
238            })
239          }
240        }
241      });
242    },
243    getBreakPoint: () => {
244      return AppStorage.Get('breakPoint');
245    }
246  }
247
248  build() {
249    Column() {
250      Flex({ direction: FlexDirection.Column, wrap: FlexWrap.NoWrap,
251        alignItems: ItemAlign.Start, alignContent: FlexAlign.SpaceAround }) {
252        Column() {
253          ToolBarComp({ controllerShow: this.controllerShow })
254          NoteContentOverViewComp()
255            .enabled(this.selectedNoteData && this.selectedNoteData.is_deleted == Delete.Yes ? false : true)
256        }
257
258        Column() {
259          Web({ src: $rawfile('editor.html'), controller: this.controllerShow })
260            .overviewModeAccess(false)
261            .javaScriptAccess(true)
262            .javaScriptProxy({
263              object: this.noteContent,
264              name: "callBackToApp", // html-->  name.method
265              methodList: ["callbackhtml", "callbackScheduledSave", "callbackPasteImage", "callbackImagePath", "addToDo", "chooseStyle", "openAlbum", "callbackGetSize", "getBreakPoint"],
266              controller: this.controllerShow
267            })
268            .onPageEnd((e) => {
269              try {
270                if (this.dpi <= 240) {
271                  this.controllerShow.runJavaScript("changeSizeToRk()")
272                } else if (this.dpi <= 320 && this.dpi > 240) {
273                  this.controllerShow.runJavaScript("changeSizeToPhone()")
274                } else {
275                  this.controllerShow.runJavaScript("changeSizeToTablet()")
276                }
277                LogUtil.info(TAG, "finish loadurl")
278                let self = this
279                this.controllerShow.runJavaScript(
280                  "RICH_EDITOR.setHtml('" + this.selectedNoteData.content_text + "')",
281                  () => {
282                    // wait for the image in the note to load
283                    setTimeout(function () {
284                      self.restoreScrollTop()
285                      self.restoreFocus()
286                    }, 100)
287                  }
288                )
289              } catch (error) {
290                LogUtil.info(TAG, 'onPageEnd error')
291              }
292
293            })
294            .imageAccess(true)
295            .onlineImageAccess(true)
296            .fileAccess(true)
297            .domStorageAccess(true)
298            .zoomAccess(false)
299            .height('100%')
300            .width('100%')
301            .onScroll((event) => {
302              this.storeScrollTop(event.yOffset)
303            })
304            .onClick(() => {
305              if (time_id) {
306                clearInterval(time_id)
307              }
308              // 添加定时器:3s自动保存
309              time_id = setInterval(() => {
310                try {
311                  this.controllerShow.runJavaScript("scheduledSaveContent()")
312                } catch (error) {
313                  LogUtil.info(TAG, 'setInterval error')
314                }
315              }, 3000)
316              LogUtil.info(TAG, "setInterval time_id : " + time_id)
317              this.editModel = true
318            })
319        }
320        .enabled(this.selectedNoteData && this.selectedNoteData.is_deleted == Delete.Yes ? false : true)
321        .flexShrink(1)
322        .margin({ top: 16 })
323        .width(StyleConstants.PERCENTAGE_100)
324      }
325      .flexShrink(1)
326      .padding({ left: 24, right: 24 })
327
328      DeleteNoteComp()
329    }
330    .height(StyleConstants.PERCENTAGE_100)
331    .width(StyleConstants.PERCENTAGE_100)
332  }
333
334  aboutToAppear(): void {
335    LogUtil.info(TAG, "aboutToAppear")
336  }
337
338  aboutToDisappear(): void {
339    clearInterval(time_id)
340    NoteUtil.refreshAll()
341    LogUtil.info(TAG, "aboutToDisappear")
342  }
343}
344
345@Component
346export struct NoteContentOverViewComp {
347  @Consume('SelectedNoteData') selectedNoteData: NoteData
348  @StorageLink('AllFolderArray') AllFolderArray: FolderData[] = []
349  @StorageLink('CheckedNoteArray') CheckedNoteArray: NoteData[] = []
350  @StorageLink('isUpdate') isUpdate: boolean = false
351  NoteDataMoveArray: FolderData[]
352  editTitleDialogCtl: CustomDialogController = new CustomDialogController({
353    builder: EditTitleDialog({ confirm: this.confirm.bind(this) }),
354    alignment: DialogAlignment.Center,
355    autoCancel: false,
356    customStyle: true,
357  })
358
359  aboutToAppear() {
360    this.NoteDataMoveArray = this.AllFolderArray.slice(2, this.AllFolderArray.length);
361    this.NoteDataMoveArray.push(this.AllFolderArray[1]);
362  }
363
364  confirm(newTitle: string) {
365    this.selectedNoteData.title = newTitle
366    this.selectedNoteData.modified_time = new Date().getTime()
367    let predicates_note = RdbStoreUtil.getRdbPredicates(TableName.NoteTable)
368    predicates_note.equalTo(NoteTableColumn.Uuid, this.selectedNoteData.uuid)
369    RdbStoreUtil.update(this.selectedNoteData.toNoteObject(), predicates_note, null)
370    // save continue data
371    let continueNote: string = JSON.stringify(this.selectedNoteData.toNoteObject())
372    AppStorage.SetOrCreate<string>('ContinueNote', continueNote)
373    LogUtil.info(TAG, 'NoteContentOverViewComp, MenuBuilder, set continue note success')
374    NoteUtil.refreshAll()
375  }
376
377  @Builder MenuBuilder() {
378    Column() {
379      Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
380        List() {
381          ForEach(this.NoteDataMoveArray, (item) => {
382            ListItem() {
383              NoteDataMoveItemCompMenu({ folderItem: item, uuid: this.selectedNoteData.folder_uuid })
384            }
385            .onClick(() => {
386              this.selectedNoteData.folder_uuid = item.uuid
387              let predicates_note = RdbStoreUtil.getRdbPredicates(TableName.NoteTable)
388              predicates_note.equalTo(NoteTableColumn.Uuid, this.selectedNoteData.uuid)
389              RdbStoreUtil.update(this.selectedNoteData.toNoteObject(), predicates_note, null)
390              // save continue data
391              let continueNote: string = JSON.stringify(this.selectedNoteData.toNoteObject())
392              AppStorage.SetOrCreate<string>('ContinueNote', continueNote)
393              LogUtil.info(TAG, 'MenuBuilder, set continue note success')
394              NoteUtil.refreshAll()
395            })
396          }, noteItem => noteItem.uuid)
397        }
398        .margin({ top: 4, bottom: 4 })
399        .listDirection(Axis.Vertical)
400        .edgeEffect(EdgeEffect.Spring)
401        .height(this.AllFolderArray.length > 12 ? 504 : (this.AllFolderArray.length - 3) * 56)
402      }
403      .backgroundColor($r('app.color.folder_color_ffffff'))
404      .width(148)
405      .padding({ left: 24, right: 24 })
406    }
407  }
408
409  build() {
410    if (this.selectedNoteData) {
411      Flex({ direction: FlexDirection.Column, wrap: FlexWrap.NoWrap,
412        justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Center }) {
413        Row() {
414          Text(this.selectedNoteData.title)
415            .id(this.isUpdate + '')
416            .fontSize(30).fontWeight(FontWeight.Medium)
417            .onClick(() => {
418              clearInterval(time_id)
419              this.editTitleDialogCtl.open()
420            })
421        }.height(40)
422        .width(StyleConstants.PERCENTAGE_100)
423
424        Row() {
425          Text(DateUtil.formateDateForNoteContent(new Date(this.selectedNoteData.modified_time)))
426            .id(this.isUpdate + '')
427            .fontSize(12)
428            .padding({ top: 4, bottom: 4 })
429            .fontColor($r("app.color.modified_time_font_color"))
430          Row() {
431            Text(FolderUtil.getFolderText(FolderUtil.getFolderData(AppStorage.Get('AllFolderArray'), this.selectedNoteData.folder_uuid)) ==
432                 folderTextMap["sys_def_myFavorites_uuid"] ? folderTextMap["sys_def_unClassified_uuid"] :
433            FolderUtil.getFolderText(FolderUtil.getFolderData(AppStorage.Get('AllFolderArray'), this.selectedNoteData.folder_uuid)))
434              .id(this.isUpdate + '')
435              .fontColor($r('app.color.folder_color_99182431'))
436              .fontSize(12)
437            Image($r('app.media.triangle'))
438              .width(6)
439              .height(12)
440              .margin({ left: 4 })
441          }
442          .id(this.isUpdate + '')
443          .padding({ left: 8, right: 8, top: 4, bottom: 4 })
444          .margin({ left: 8 })
445          .borderRadius(16)
446          .backgroundColor(NoteUtil.getNoteBgColor(AppStorage.Get('AllFolderArray'), this.selectedNoteData.folder_uuid, SysDefFolderUuid.AllNotes, false))
447          .bindMenu(this.MenuBuilder)
448        }.alignItems(VerticalAlign.Top).height(40).width(StyleConstants.PERCENTAGE_100)
449      }
450      .opacity(this.selectedNoteData.is_deleted == Delete.Yes ? 0.4 : 1)
451      .width(StyleConstants.PERCENTAGE_100)
452      .height(82)
453    }
454  }
455}
456
457@Component
458export struct ToolBarComp {
459  @Consume('SelectedNoteData') selectedNoteData: NoteData
460  @Consume('SelectedFolderData') selectedFolderData: FolderData
461  @Consume('EditModel') editModel: boolean
462  @StorageLink('AllNoteArray') AllNoteArray: NoteData[] = AppStorage.Link('AllNoteArray')
463  controllerShow: WebviewController
464
465  onDeleteConfirm() {
466    if (this.selectedFolderData.uuid != SysDefFolderUuid.RecentDeletes) {
467      this.selectedNoteData.is_deleted = Delete.Yes
468      this.selectedNoteData.deleted_time = new Date().getTime()
469      // update note to db
470      let predicates_note = RdbStoreUtil.getRdbPredicates(TableName.NoteTable)
471      predicates_note.equalTo(NoteTableColumn.Uuid, this.selectedNoteData.uuid)
472      RdbStoreUtil.update(this.selectedNoteData.toNoteObject(), predicates_note, null)
473      routePage()
474    } else {
475      NoteUtil.removeNoteData(this.AllNoteArray, this.selectedNoteData.uuid)
476      // delete note from db
477      let predicates_note = RdbStoreUtil.getRdbPredicates(TableName.NoteTable)
478      predicates_note.equalTo(NoteTableColumn.Uuid, this.selectedNoteData.uuid)
479      RdbStoreUtil.delete(predicates_note, null)
480      routePage()
481    }
482    AppStorage.SetOrCreate('isUpdate', true)
483  }
484
485  noteDataDeleteDialogCtl: CustomDialogController = new CustomDialogController({
486    builder: DeleteDialog({ onConfirm: this.onDeleteConfirm.bind(this), multiSelect: true }),
487    alignment: DialogAlignment.Bottom,
488    autoCancel: false,
489    customStyle: true,
490  })
491
492  build() {
493    Flex({ direction: FlexDirection.Row, wrap: FlexWrap.NoWrap,
494      justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Center }) {
495
496      Image($r('app.media.back'))
497        .height(24)
498        .width(24)
499        .responseRegion({ width: 54, height: 54 })
500        .onClick(() => {
501          try {
502            this.controllerShow.runJavaScript("getHtmlContent()")
503            // 清除定时器
504            if (time_id != undefined) {
505              LogUtil.info(TAG, "back, clearInterval time_id : " + time_id)
506              clearInterval(time_id)
507            }
508            router.back()
509            NoteUtil.refreshAll()
510          } catch (error) {
511            LogUtil.info(TAG, 'back error')
512          }
513        })
514
515      if (this.editModel == false) {
516        Row({ space: StyleConstants.SPACE_24 }) {
517          Image(this.selectedNoteData.is_favorite == Favorite.Yes ? $r('app.media.favorite') : $r('app.media.favorite_cancel'))
518            .height(24).width(24)
519            .onClick(() => {
520              try {
521                this.selectedNoteData.is_favorite = (this.selectedNoteData.is_favorite == Favorite.Yes ? Favorite.No : Favorite.Yes)
522                // update note to db
523                let predicates_note = RdbStoreUtil.getRdbPredicates(TableName.NoteTable)
524                predicates_note.equalTo(NoteTableColumn.Uuid, this.selectedNoteData.uuid)
525                RdbStoreUtil.update(this.selectedNoteData.toNoteObject(), predicates_note, null)
526                if (this.selectedFolderData.uuid === SysDefFolderUuid.MyFavorites) {
527                  this.selectedNoteData = NoteUtil.getFirstNoteData(AppStorage.Get('AllNoteArray'), SysDefFolderUuid.MyFavorites)
528                  this.controllerShow.runJavaScript(
529                    "RICH_EDITOR.setHtml('" + this.selectedNoteData.content_text + "')"
530                  )
531                  // save continue data
532                  let continueNote: string = JSON.stringify(this.selectedNoteData.toNoteObject())
533                  AppStorage.SetOrCreate<string>('ContinueNote', continueNote)
534                  LogUtil.info(TAG, "ToolBarComp, set continue note success")
535                }
536                NoteUtil.refreshAll()
537              } catch (error) {
538                LogUtil.info(TAG, 'favorite error')
539              }
540            })
541          Image($r('app.media.delete')).height(24).width(24)
542            .onClick(() => {
543              this.noteDataDeleteDialogCtl.open()
544            })
545        }.width(72)
546        .visibility(this.selectedNoteData.is_deleted == Delete.Yes ? Visibility.None : Visibility.Visible)
547      } else {
548        Row({ space: StyleConstants.SPACE_6 }) {
549          Button({ type: ButtonType.Normal, stateEffect: true }) {
550            Image($r('app.media.undo')).height(24).width(24)
551              .onClick(() => {
552                try {
553                  // 退出键盘
554                  // @ts-ignore
555                  inputMethod.getController().stopInputSession();
556                  this.controllerShow.runJavaScript("javascript:RICH_EDITOR.undo()")
557                } catch (error) {
558                  LogUtil.info(TAG, 'undo error')
559                }
560              })
561          }.width(42)
562          .height(42)
563          .borderRadius(8)
564          .backgroundColor($r('app.color.color_fffffB'))
565
566          Button({ type: ButtonType.Normal, stateEffect: true }) {
567            Image($r('app.media.todo')).height(24).width(24)
568              .onClick(() => {
569                try {
570                  // 退出键盘
571                  // @ts-ignore
572                  inputMethod.getController().stopInputSession();
573                  this.controllerShow.runJavaScript("javascript:RICH_EDITOR.redo()")
574                } catch (error) {
575                  LogUtil.info(TAG, 'todo error')
576                }
577              })
578          }.width(42)
579          .height(42)
580          .borderRadius(8)
581          .backgroundColor($r('app.color.color_fffffB'))
582
583          Button({ type: ButtonType.Normal, stateEffect: true }) {
584            Image($r('app.media.tick_thin')).height(24).width(24)
585              .onClick(() => {
586                try {
587                  // 保存笔记信息到数据库
588                  this.controllerShow.runJavaScript("getHtmlContent()")
589                  this.editModel = false
590                } catch (error) {
591                  LogUtil.info(TAG, 'tick_thin error')
592                }
593              })
594          }.width(42)
595          .height(42)
596          .borderRadius(8)
597          .backgroundColor($r('app.color.color_fffffB'))
598        }
599        .width(130)
600        .visibility(this.selectedNoteData.is_deleted == Delete.Yes ? Visibility.None : Visibility.Visible)
601      }
602    }
603    .width(StyleConstants.PERCENTAGE_100)
604    .height(40)
605  }
606}
607
608@Component
609export struct DeleteNoteComp {
610  @StorageLink('CheckedNoteArray') CheckedNoteArray: NoteData[] = []
611  @StorageLink('AllNoteArray') AllNoteArray: NoteData[] = AppStorage.Link('AllNoteArray')
612  @Consume('SelectedFolderData') selectedFolderData: FolderData
613  @Consume('RefreshFlag') refreshFlag: number
614  @Consume('SelectedNoteData') selectedNoteData: NoteData;
615  noteDataDeleteDialogCtlBottom: CustomDialogController = new CustomDialogController({
616    builder: DeleteDialog({ onConfirm: this.onDeleteConfirm.bind(this), multiSelect: true }),
617    alignment: DialogAlignment.Bottom,
618    autoCancel: false,
619    customStyle: true,
620  })
621
622  onDeleteConfirm() {
623    if (this.selectedFolderData.uuid != SysDefFolderUuid.RecentDeletes) {
624      this.selectedNoteData.is_deleted = Delete.Yes
625      this.selectedNoteData.deleted_time = new Date().getTime()
626      // update note to db
627      let predicates_note = RdbStoreUtil.getRdbPredicates(TableName.NoteTable)
628      predicates_note.equalTo(NoteTableColumn.Uuid, this.selectedNoteData.uuid)
629      RdbStoreUtil.update(this.selectedNoteData.toNoteObject(), predicates_note, null)
630      routePage()
631    } else {
632      NoteUtil.removeNoteData(this.AllNoteArray, this.selectedNoteData.uuid)
633      // delete note from db
634      let predicates_note = RdbStoreUtil.getRdbPredicates(TableName.NoteTable)
635      predicates_note.equalTo(NoteTableColumn.Uuid, this.selectedNoteData.uuid)
636      RdbStoreUtil.delete(predicates_note, null)
637      NoteUtil.refreshAll()
638      routePage()
639    }
640    AppStorage.SetOrCreate('isUpdate', false)
641  }
642
643  build() {
644    Flex({ direction: FlexDirection.Row, wrap: FlexWrap.Wrap, justifyContent: FlexAlign.SpaceBetween }) {
645      Column() {
646        Image($r('app.media.delete'))
647          .width(24)
648          .height(24)
649          .responseRegion({ x: -15.0, y: -15.0, width: 54, height: 54 })
650          .onClick(() => {
651            this.noteDataDeleteDialogCtlBottom.open()
652          })
653        Text($r("app.string.delete"))
654          .fontSize(10)
655          .fontColor($r('app.color.delete_font_color'))
656          .padding({ top: 5 })
657      }
658      .height("100%")
659      .width(180)
660      .justifyContent(FlexAlign.Center)
661      .alignItems(HorizontalAlign.Center)
662
663      Column() {
664        Image($r('app.media.recover'))
665          .width(24)
666          .height(24)
667          .responseRegion({ x: -15.0, y: -15.0, width: 54, height: 54 })
668          .onClick(() => {
669            this.selectedNoteData.is_deleted = Delete.No
670            this.selectedNoteData.deleted_time = 0
671            let context: any = getContext(this)
672            let resource = {
673              bundleName: "com.ohos.note",
674              moduleName: "default",
675              id: $r('app.string.restore').id
676            };
677            context.resourceManager.getString(resource, (error, value) => {
678              if (error != null) {
679                console.log("error is " + error);
680              } else {
681                prompt.showToast({ message: value, duration: 2000 });
682              }
683            });
684            this.refreshFlag = (this.refreshFlag == 0 ? 1 : 0)
685            // update note to db
686            let predicates_note = RdbStoreUtil.getRdbPredicates(TableName.NoteTable)
687            predicates_note.equalTo(NoteTableColumn.Uuid, this.selectedNoteData.uuid)
688            RdbStoreUtil.update(this.selectedNoteData.toNoteObject(), predicates_note, null)
689            NoteUtil.refreshAll()
690          })
691        Text($r("app.string.recover"))
692          .fontSize(10)
693          .fontColor($r('app.color.recover_font_color'))
694          .padding({ top: 5 })
695      }
696      .height("100%")
697      .width(180)
698      .justifyContent(FlexAlign.Center)
699      .alignItems(HorizontalAlign.Center)
700    }
701    .width(360)
702    .height(56)
703    .visibility(this.selectedNoteData.is_deleted == Delete.Yes ?
704    Visibility.Visible : Visibility.None)
705  }
706}
707
708@Component
709struct NoteDataMoveItemCompMenu {
710  @StorageLink('CheckedNoteArray') CheckedNoteArray: NoteData[] = []
711  @StorageLink('AllFolderArray') AllFolderArray: FolderData[] = []
712  @StorageLink('isUpdate') isUpdate: boolean = false
713  folderItem: FolderData
714  uuid: String
715
716  build() {
717    Flex({ alignItems: ItemAlign.Center, wrap: FlexWrap.NoWrap, justifyContent: FlexAlign.Center }) {
718      Flex({ alignItems: ItemAlign.Center, wrap: FlexWrap.NoWrap }) {
719        Image(FolderUtil.getFolderIcon(this.folderItem.uuid))
720          .id(this.isUpdate + '')
721          .objectFit(ImageFit.Fill)
722          .width(24)
723          .height(24)
724          .flexShrink(0)
725          .fillColor(FolderUtil.getFolderIconColor(this.AllFolderArray, this.folderItem.uuid, this.folderItem.uuid == this.uuid))
726      }
727      .width(24)
728
729      Column() {
730        Flex({ alignItems: ItemAlign.Center, wrap: FlexWrap.NoWrap, justifyContent: FlexAlign.SpaceBetween }) {
731          Text(FolderUtil.getFolderText(this.folderItem))
732            .id(this.isUpdate + '')
733            .fontSize(16)
734            .fontColor(FolderUtil.getFolderIconColor(this.AllFolderArray, this.folderItem.uuid == this.uuid ? this.folderItem.uuid : '', this.folderItem.uuid == this.uuid))
735            .textAlign(TextAlign.Center)
736            .maxLines(1)
737            .textOverflow({ overflow: TextOverflow.Ellipsis })
738            .flexShrink(1)
739        }
740        .width('100%')
741        .height(55)
742
743        if (this.folderItem.uuid != SysDefFolderUuid.UnClassified) {
744          Divider()
745            .color($r("app.color.divider_color_e4e4e4"))
746            .strokeWidth(1)
747        }
748
749      }
750      .padding({ left: 16 })
751    }
752    .id(this.isUpdate + '')
753    .width('100%')
754    .height(56)
755    .visibility(FolderUtil.isFolderMoveIn(this.folderItem) ? Visibility.Visible : Visibility.None)
756  }
757}