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