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