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