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