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