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 FolderData from '@ohos/utils/src/main/ets/default/model/databaseModel/FolderData' 18import NoteData from '@ohos/utils/src/main/ets/default/model/databaseModel/NoteData' 19import { 20 TableName, 21 NoteTableColumn, 22 SysDefFolderUuid, 23 Favorite, 24 Delete, 25 Top, 26 NoteType 27} from '@ohos/utils/src/main/ets/default/model/databaseModel/EnumData' 28import { NoteDataMoveDialog, DeleteDialog } from './CusDialogComp' 29import RdbStoreUtil from '@ohos/utils/src/main/ets/default/baseUtil/RdbStoreUtil' 30import prompt from '@system.prompt' 31import NoteUtil from '@ohos/utils/src/main/ets/default/baseUtil/NoteUtil' 32import FolderUtil from '@ohos/utils/src/main/ets/default/baseUtil/FolderUtil' 33import SearchModel from '@ohos/utils/src/main/ets/default/model/searchModel/SearchModel' 34import { LogUtil } from '@ohos/utils/src/main/ets/default/baseUtil/LogUtil' 35import router from '@system.router'; 36import inputMethod from '@ohos.inputMethod'; 37 38const TAG = "NoteListComp" 39 40async function routePage() { 41 let options = { 42 uri: 'pages/NoteContentHome' 43 } 44 try { 45 await router.push(options) 46 } catch (err) { 47 LogUtil.info(TAG, "fail callback") 48 } 49} 50 51// Note list component 52@Component 53export struct NoteListComp { 54 @StorageLink('AllFolderArray') AllFolderArray: FolderData[] = AppStorage.Link('AllFolderArray') 55 @Consume('SelectedFolderData') selectedFolderData: FolderData 56 @Consume('Search') search: boolean 57 controllerShow: WebviewController 58 @Consume('AsideWidth') asideWidth: number 59 60 build() { 61 Flex({ direction: FlexDirection.Column }) { 62 Flex({ direction: FlexDirection.Column }) { 63 NoteOverViewComp({ controllerShow: this.controllerShow }) 64 Column() { 65 } 66 .height(this.search ? 15 : 0) 67 68 NoteItemListComp({ controllerShow: this.controllerShow }) 69 } 70 .width('100%') 71 .flexShrink(1) 72 73 Column() { 74 OperateNoteCompForPortrait() 75 } 76 .flexShrink(0) 77 } 78 .height('100%') 79 .width('100%') 80 } 81 82 aboutToAppear(): void { 83 AppStorage.SetOrCreate('isUpdate', false) 84 LogUtil.info(TAG, "aboutToAppear") 85 } 86 87 aboutToDisappear(): void { 88 LogUtil.info(TAG, "aboutToDisappear") 89 } 90} 91 92@Component 93struct NoteOverViewComp { 94 @StorageLink('AllNoteArray') AllNoteArray: NoteData[] = AppStorage.Link('AllNoteArray') 95 @StorageLink('breakPoint') breakPoints: string = AppStorage.Get('breakPoint') 96 @StorageLink('CheckedNoteArray') CheckedNoteArray: NoteData[] = [] 97 @Consume('SelectedFolderData') selectedFolderData: FolderData 98 @Consume('RefreshFlag') refreshFlag: number 99 @Consume('SectionStatus') sectionStatus: number 100 @Consume("Longpress") longpress: boolean 101 @Consume('ExpandStatus') expandStatus: boolean 102 @Consume('Search') search: boolean 103 @Consume('PortraitModel') portraitModel: boolean 104 controllerShow: WebviewController 105 @State noteNumber: number = undefined 106 @StorageLink('isUpdate') @Watch('notesNumberChange') isUpdate: boolean = false 107 @Consume('AsideWidth') asideWidth: number 108 @State isShow: boolean = false 109 110 notesNumberChange() { 111 let noteNumbers = FolderUtil.getNoteCount(AppStorage.Get('AllNoteArray'), this.selectedFolderData.uuid) 112 if (noteNumbers == 0) { 113 this.isShow = false 114 } else { 115 this.isShow = true 116 } 117 } 118 119 build() { 120 Flex({ justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Center }) { 121 Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center }) { 122 Column() { 123 Image($r("app.media.suojin_back")) 124 .height(24) 125 .width(24) 126 .responseRegion({ 127 x: -15.0, 128 y: -15.0, 129 width: 54, 130 height: 54 131 }) 132 .margin({ right: 24 }) // 两分栏时缩进图片与右边有个24的间距 133 .visibility(this.breakPoints == 'lg' && this.sectionStatus == 3 ? Visibility.None : Visibility.Visible) 134 .onClick(() => { 135 if (this.breakPoints == 'sm' || this.breakPoints == 'md') { 136 animateTo({ duration: 200 }, () => { 137 this.expandStatus = !this.expandStatus 138 }) 139 } else { 140 this.asideWidth = 200 141 this.sectionStatus = (this.sectionStatus == 3 ? 2 : 3) 142 // save continue data 143 AppStorage.SetOrCreate<number>('ContinueSection', this.sectionStatus) 144 LogUtil.info(TAG, "NoteOverViewComp, set continue section success") 145 } 146 }) 147 }.alignItems(HorizontalAlign.Center) 148 149 Flex({ 150 direction: FlexDirection.Column, 151 wrap: FlexWrap.Wrap, 152 justifyContent: FlexAlign.Center, 153 alignItems: ItemAlign.Start 154 }) { 155 Text(FolderUtil.getFolderText(this.selectedFolderData)) 156 .id(this.isUpdate + '') 157 .maxLines(1) 158 .fontSize(30) 159 .fontColor($r("app.color.all_notes_font_color")) 160 .fontWeight(FontWeight.Medium) 161 .textOverflow({ overflow: TextOverflow.Ellipsis }) 162 Row() { 163 Text(FolderUtil.getNoteCount(AppStorage.Get('AllNoteArray'), this.selectedFolderData.uuid).toString()) 164 .id(this.isUpdate + '') 165 .maxLines(1) 166 .fontSize(14) 167 .fontColor($r("app.color.num_of_notes_font_color")) 168 Text($r("app.string.noteslist")) 169 .fontSize(14) 170 .fontColor($r("app.color.num_of_notes_font_color")) 171 .textOverflow({ overflow: TextOverflow.Ellipsis }) 172 } 173 .margin({ top: 5 }) 174 .visibility(this.isShow ? Visibility.Visible : Visibility.None) 175 }.visibility(this.longpress ? Visibility.None : Visibility.Visible) 176 177 Row() { 178 Image($r("app.media.cross")) 179 .height(24) 180 .width(24) 181 .responseRegion({ 182 x: -15.0, 183 y: -15.0, 184 width: 54, 185 height: 54 186 }) 187 .onClick(() => { 188 this.longpress = false 189 this.refreshFlag = (this.refreshFlag == 0 ? 1 : 0) 190 NoteUtil.unsetAllNotesChecked(this.CheckedNoteArray) 191 }) 192 Text(this.CheckedNoteArray.length == 0 ? $r("app.string.none_selected") : $r("app.string.selected", this.CheckedNoteArray.length)) 193 .fontSize(20) 194 .fontColor($r("app.color.note_selected_font_color")) 195 .margin({ left: 16 }) 196 .textOverflow({ overflow: TextOverflow.Ellipsis }) 197 .fontWeight(FontWeight.Medium) 198 }.alignItems(VerticalAlign.Center) 199 .visibility(this.longpress ? Visibility.Visible : Visibility.None) 200 }.padding({ top: 8, bottom: 8 }) 201 .height('100%') 202 203 AddNoteComp({ controllerShow: this.controllerShow }) 204 OperateNoteComp({ controllerShow: this.controllerShow }) 205 Text(this.refreshFlag.toString()).visibility(Visibility.None) 206 } 207 .width('100%') 208 .height(82) 209 .padding({ 210 left: this.sectionStatus == 2 ? 24 : 36, 211 right: 24 212 }) // 两分栏时缩进图标与左侧不需要间距 213 .visibility(this.search ? Visibility.None : Visibility.Visible) 214 } 215} 216 217@Component 218export struct NoteItemComp { 219 public noteItem: NoteData 220 public spans: any[] 221 controllerShow: WebviewController 222 @Consume('SelectedFolderData') selectedFolderData: FolderData 223 @Consume('SelectedNoteData') selectedNoteData: NoteData 224 @StorageLink('AllFolderArray') AllFolderArray: FolderData[] = AppStorage.Link('AllFolderArray') 225 @StorageLink('CheckedNoteArray') CheckedNoteArray: NoteData[] = [] 226 @Consume('ChooseNote') chooseNote: boolean 227 @Consume('RefreshFlag') refreshFlag: number 228 @Consume('Search') search: boolean 229 @Consume('selectedAll') selectedAll: boolean 230 @Consume('PortraitModel') portraitModel: boolean 231 @State isChecked: boolean = undefined 232 @Consume('Longpress') @Watch('isLongPress') longpress: boolean 233 @StorageLink('isUpdate') isUpdate: boolean = false 234 235 isLongPress() { 236 if (this.longpress) { 237 this.isChecked = false 238 } 239 } 240 241 updateAndGetChecked() { 242 this.isChecked = NoteUtil.isNoteChecked(this.CheckedNoteArray, this.noteItem) 243 return this.isChecked 244 } 245 246 build() { 247 Flex({ justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Center }) { 248 Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center }) { 249 Text(JSON.stringify(this.refreshFlag)).visibility(Visibility.None) // 用于强制刷新使用 250 Column({ space: 2 }) { 251 Row({ space: 8 }) { 252 Image($r("app.media.verticalBar")) 253 .id(this.isUpdate + '') 254 .height(16) 255 .width(4) 256 .fillColor(NoteUtil.getVerticalBarBgColor(AppStorage.Get('AllFolderArray'), this.noteItem.folder_uuid)) 257 Text(this.noteItem.title) 258 .fontSize(16) 259 .maxLines(1) 260 .textOverflow({ overflow: TextOverflow.Ellipsis }) 261 } 262 263 Row({ space: 4 }) { 264 Text(DateUtil.formateDateForNoteTitle(new Date(this.noteItem.modified_time))) 265 .id(this.isUpdate + '') 266 .maxLines(1) 267 .fontSize(14) 268 .fontColor($r("app.color.list_modified_time_font_color")) 269 .fontWeight(FontWeight.Regular) 270 .textOverflow({ overflow: TextOverflow.Ellipsis }) 271 Image($r("app.media.favorite")) 272 .height(16) 273 .width(16) 274 .visibility(this.noteItem.is_favorite == Favorite.Yes ? Visibility.Visible : Visibility.None) 275 Image($r("app.media.topped")) 276 .height(16) 277 .width(16) 278 .visibility(this.noteItem.is_top == Top.Yes ? Visibility.Visible : Visibility.None) 279 } 280 .padding({ left: 12 }) 281 }.alignItems(HorizontalAlign.Start) 282 }.flexShrink(1) 283 284 Flex({ justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Center }) { 285 Stack({ alignContent: Alignment.Center }) { 286 Image(this.noteItem.content_img) 287 .id(this.isUpdate + '') 288 .height(47) 289 .width(47) 290 .borderRadius(12) 291 .border({ width: 0.5, color: '#19182431' }) 292 .visibility(this.noteItem.content_img ? Visibility.Visible : Visibility.None) 293 } 294 295 Stack({ alignContent: Alignment.Center }) { 296 Image($r("app.media.unChecked")) 297 .height(24) 298 .width(24) 299 Image($r("app.media.checked")) 300 .width(24) 301 .height(24) 302 .visibility(this.updateAndGetChecked() ? Visibility.Visible : Visibility.None) 303 .id(this.isUpdate + '') 304 }.width(24) 305 .height(24) 306 .visibility(this.longpress ? Visibility.Visible : Visibility.None) 307 } 308 .flexShrink(0) 309 .height(48) 310 .width(this.longpress ? 80 : 48) 311 } 312 .width('100%') 313 .height(72) 314 .padding({ 315 left: 16, 316 right: 12, 317 top: 4, 318 bottom: 4 319 }) 320 .borderRadius(24) 321 .linearGradient({ 322 direction: GradientDirection.Right, 323 colors: this.selectedNoteData?.uuid == this.noteItem.uuid ? [[0xffcdae, 0.0], [0xFfece2, 1.0]] : [[0xffffff, 0.0], [0xffffff, 1.0]] 324 }) 325 .onClick(() => { 326 if (this.search) { 327 this.search = false 328 AppStorage.SetOrCreate<boolean>('Search', this.search) 329 return 330 } 331 if (this.longpress) { 332 if (NoteUtil.isNoteChecked(this.CheckedNoteArray, this.noteItem)) { 333 NoteUtil.unsetNoteChecked(this.CheckedNoteArray, this.noteItem) 334 this.refreshFlag = (this.refreshFlag == 0 ? 1 : 0) 335 this.isChecked = NoteUtil.isNoteChecked(this.CheckedNoteArray, this.noteItem) 336 } else { 337 NoteUtil.setNoteChecked(this.CheckedNoteArray, this.noteItem) 338 this.refreshFlag = (this.refreshFlag == 0 ? 1 : 0) 339 this.isChecked = NoteUtil.isNoteChecked(this.CheckedNoteArray, this.noteItem) 340 } 341 return; 342 } else { 343 this.selectedNoteData = this.noteItem 344 this.chooseNote = true 345 // save continue data 346 let continueNote: string = JSON.stringify(this.selectedNoteData?.toNoteObject()) 347 AppStorage.SetOrCreate<string>('ContinueNote', continueNote) 348 LogUtil.info(TAG, "NoteItemComp, set continue note success") 349 } 350 if (this.portraitModel == false) { 351 this.controllerShow.runJavaScript( 352 "RICH_EDITOR.setHtml('" + this.selectedNoteData?.content_text + "')" 353 ) 354 this.controllerShow.runJavaScript( 355 "RICH_EDITOR.cancelSelection()" 356 ) 357 } 358 if (this.portraitModel == true) { 359 AppStorage.SetOrCreate<NoteData>('NewNote', this.selectedNoteData) 360 AppStorage.SetOrCreate<FolderData>('NewFolder', this.selectedFolderData) 361 routePage() 362 } 363 this.selectedAll = this.CheckedNoteArray.length == 364 NoteUtil.getNoteDataArray(AppStorage.Get('AllNoteArray'), this.selectedFolderData.uuid).length 365 this.refreshFlag = (this.refreshFlag == 0 ? 1 : 0) 366 }) 367 .gesture( 368 GestureGroup(GestureMode.Exclusive, 369 // 长按:对笔记列表进行操作 370 LongPressGesture() 371 .onAction(() => { 372 if (this.longpress == false) { 373 this.longpress = true 374 NoteUtil.setNoteChecked(this.CheckedNoteArray, this.noteItem) 375 this.isChecked = NoteUtil.isNoteChecked(this.CheckedNoteArray, this.noteItem) 376 } 377 }) 378 ) 379 ) 380 381 } 382} 383 384@Component 385export struct NoteItemListComp { 386 @StorageLink('AllNoteArray') AllNoteArray: NoteData[] = AppStorage.Link('AllNoteArray') 387 @Consume('SelectedFolderData') selectedFolderData: FolderData 388 @Consume('RefreshFlag') refreshFlag: number 389 @Consume('Longpress') longpress: boolean 390 @Consume('Search') search: boolean 391 @Consume @Watch('doSearch') inputKeyword: string 392 @Consume('SearchResultList') searchResultList: NoteData[] 393 @Consume('SelectedNoteData') selectedNoteData: NoteData 394 @Consume('PortraitModel') portraitModel: boolean 395 @State dateList: NoteData[] = [] 396 controllerShow: WebviewController 397 @StorageLink('isUpdate') @Watch('updateList') isUpdate: boolean = false 398 399 updateList() { 400 if (this.isUpdate) { 401 this.dateList = NoteUtil.getNoteDataArray(AppStorage.Get('AllNoteArray'), this.selectedFolderData.uuid) 402 } 403 this.isUpdate = false 404 this.doSearch() 405 } 406 407 aboutToAppear() { 408 LogUtil.info(TAG, "inputKeyWord:" + this.inputKeyword) 409 this.inputKeyword = '' 410 this.dateList = NoteUtil.getNoteDataArray(AppStorage.Get('AllNoteArray'), this.selectedFolderData.uuid) 411 } 412 413 doSearch() { 414 if (this.inputKeyword.length == 0) { 415 return 416 } 417 SearchModel.search(NoteUtil.getNoteDataArray(AppStorage.Get('AllNoteArray'), this.selectedFolderData.uuid), this.inputKeyword) 418 .then((result: NoteData[]) => { 419 LogUtil.info(TAG, "result size " + result.length.toString()) 420 this.searchResultList = result 421 if (this.searchResultList.length != 0) { 422 this.selectedNoteData = this.searchResultList[0] 423 } else { 424 this.selectedNoteData = NoteUtil.getFirstNoteData(AppStorage.Get('AllNoteArray'), this.selectedFolderData.uuid) 425 } 426 if (this.portraitModel == false) { 427 this.controllerShow.runJavaScript( 428 "RICH_EDITOR.setHtml('" + this.selectedNoteData?.content_text + "')" 429 ) 430 } 431 // save continue data 432 let continueNote: string = JSON.stringify(this.selectedNoteData?.toNoteObject()) 433 AppStorage.SetOrCreate<string>('ContinueNote', continueNote) 434 LogUtil.info(TAG, "doSearch, set continue note success") 435 this.refreshFlag = (this.refreshFlag == 0 ? 1 : 0) 436 }) 437 } 438 439 build() { 440 Column() { 441 Text(this.refreshFlag.toString()).visibility(Visibility.None) 442 Flex() { 443 SearchComp() 444 } 445 .id(this.isUpdate + '') 446 .width("100%") 447 .padding({ left: 24, right: 24, bottom: 12 }) 448 .visibility((FolderUtil.getNoteCount(AppStorage.Get('AllNoteArray'), this.selectedFolderData.uuid) == 0) ? Visibility.None : Visibility.Visible) 449 450 Stack() { 451 Flex({ direction: FlexDirection.Column }) { 452 Flex({ justifyContent: FlexAlign.Center }) { 453 Text($r("app.string.permanently_delete_tips")) 454 .fontSize(12) 455 .fontColor($r("app.color.Recently_delete_prompt_font_color")) 456 } 457 .padding({ bottom: this.selectedFolderData.uuid == SysDefFolderUuid.RecentDeletes ? 12 : 0 }) 458 .width('100%') 459 .visibility(this.selectedFolderData.uuid == SysDefFolderUuid.RecentDeletes 460 && FolderUtil.getNoteCount(AppStorage.Get('AllNoteArray'), this.selectedFolderData.uuid) > 0 ? Visibility.Visible : Visibility.None) 461 462 Column() { 463 List({ initialIndex: 0 }) { 464 ListItem() { 465 Column({ space: 8 }) { 466 Image($r('app.media.emptyPage')) 467 .width(120) 468 .height(120) 469 Text($r("app.string.Empty_page")) 470 .fontSize(12) 471 .fontColor($r("app.color.Empty_page_font_color")) 472 } 473 } 474 .id(this.isUpdate + '') 475 .width('100%') 476 .height('100%') 477 .padding({ bottom: 120 }) 478 .visibility((FolderUtil.getNoteCount(AppStorage.Get('AllNoteArray'), this.selectedFolderData.uuid) == 0) ? Visibility.Visible : Visibility.None) 479 480 ForEach(this.inputKeyword.length == 0 ? 481 this.dateList : this.searchResultList, (noteItem) => { 482 ListItem() { 483 Column() { 484 NoteItemComp({ 485 noteItem: noteItem, 486 spans: SearchModel.splitToHighlightText(noteItem.title, this.inputKeyword), 487 controllerShow: this.controllerShow 488 }) 489 } 490 .padding({ left: 24, right: 24, bottom: 12 }) 491 } 492 .visibility((FolderUtil.getNoteCount(AppStorage.Get('AllNoteArray'), this.selectedFolderData.uuid) == 0) ? Visibility.None : Visibility.Visible) 493 }, noteItem => JSON.stringify(noteItem)) 494 } 495 .id(this.isUpdate + '') 496 .margin((FolderUtil.getNoteCount(AppStorage.Get('AllNoteArray'), this.selectedFolderData.uuid) == 0) ? { 497 bottom: 0 498 } : { 499 bottom: 56 500 }) 501 .layoutWeight(1) 502 .listDirection(Axis.Vertical) 503 .edgeEffect(EdgeEffect.Spring) 504 } 505 .layoutWeight(1) 506 .height("100%") 507 .margin({ top: this.search ? 8 : 0 }) 508 } 509 .height("100%") 510 .width("100%") 511 512 // search input mask 513 Column() { 514 } 515 .height("100%") 516 .width("100%") 517 .backgroundColor("#18181A") 518 .opacity(0.1) 519 .visibility(this.search ? Visibility.Visible : Visibility.Hidden) 520 } 521 } 522 .onClick(() => { 523 this.search = false 524 inputMethod.getController().stopInputSession() 525 AppStorage.SetOrCreate<boolean>('Search', this.search) 526 }) 527 } 528} 529 530@Component 531export struct OperateNoteComp { 532 @Consume('Longpress') longpress: boolean 533 @StorageLink('CheckedNoteArray') CheckedNoteArray: NoteData[] = [] 534 @StorageLink('AllNoteArray') AllNoteArray: NoteData[] = AppStorage.Link('AllNoteArray') 535 @Consume('SelectedFolderData') selectedFolderData: FolderData 536 @Consume('RefreshFlag') refreshFlag: number 537 @Consume('SelectedNoteData') selectedNoteData: NoteData 538 @Consume('PortraitModel') portraitModel: boolean 539 @Consume('selectedAll') selectedAll: boolean 540 @StorageLink('isUpdate') isUpdate: boolean = false 541 controllerShow: WebviewController 542 noteDataMoveDialogCtl: CustomDialogController = new CustomDialogController({ 543 builder: NoteDataMoveDialog({ onConfirm: this.onMoveConfirm.bind(this) }), 544 alignment: DialogAlignment.Center, 545 autoCancel: false, 546 customStyle: true, 547 }) 548 549 aboutToDisappear() { 550 this.noteDataMoveDialogCtl = null 551 this.noteDataDeleteDialogCtl = null 552 } 553 554 onMoveConfirm(folderUuid: string) { 555 this.CheckedNoteArray.forEach((noteItem) => { 556 noteItem.folder_uuid = folderUuid 557 // update note to db 558 let predicates_note = RdbStoreUtil.getRdbPredicates(TableName.NoteTable) 559 predicates_note.equalTo(NoteTableColumn.Uuid, noteItem.uuid) 560 RdbStoreUtil.update(noteItem.toNoteObject(), predicates_note, null) 561 }) 562 this.selectedNoteData = NoteUtil.getFirstNoteData(this.AllNoteArray, this.selectedFolderData.uuid) 563 // save continue data 564 let continueNote: string = JSON.stringify(this.selectedNoteData?.toNoteObject()) 565 AppStorage.SetOrCreate<string>('ContinueNote', continueNote) 566 LogUtil.info(TAG, "onMoveConfirm, set continue note success") 567 if (this.portraitModel == false) { 568 this.controllerShow.runJavaScript("RICH_EDITOR.setHtml('" + this.selectedNoteData?.content_text + "')") 569 } 570 this.longpress = false 571 this.refreshFlag = (this.refreshFlag == 0 ? 1 : 0) 572 NoteUtil.unsetAllNotesChecked(this.CheckedNoteArray) 573 NoteUtil.refreshAll() 574 } 575 576 noteDataDeleteDialogCtl: CustomDialogController = new CustomDialogController({ 577 builder: DeleteDialog({ onConfirm: this.onDeleteConfirm.bind(this), multiSelect: true }), 578 alignment: DialogAlignment.Center, 579 autoCancel: false, 580 customStyle: true, 581 }) 582 583 onDeleteConfirm() { 584 if (this.selectedFolderData.uuid != SysDefFolderUuid.RecentDeletes) { 585 this.CheckedNoteArray.forEach((noteItem: NoteData) => { 586 noteItem.is_deleted = Delete.Yes 587 noteItem.deleted_time = new Date().getTime() 588 // update note to db 589 let predicates_note = RdbStoreUtil.getRdbPredicates(TableName.NoteTable) 590 predicates_note.equalTo(NoteTableColumn.Uuid, noteItem.uuid) 591 RdbStoreUtil.update(noteItem.toNoteObject(), predicates_note, null) 592 }) 593 } else { 594 this.CheckedNoteArray.forEach((noteItem: NoteData) => { 595 NoteUtil.removeNoteData(this.AllNoteArray, noteItem.uuid) 596 // delete note from db 597 let predicates_note = RdbStoreUtil.getRdbPredicates(TableName.NoteTable) 598 predicates_note.equalTo(NoteTableColumn.Uuid, noteItem.uuid) 599 RdbStoreUtil.delete(predicates_note, null) 600 }) 601 } 602 NoteUtil.unsetAllNotesChecked(this.CheckedNoteArray) 603 this.refreshFlag = (this.refreshFlag == 0 ? 1 : 0) 604 this.longpress = false 605 this.selectedNoteData = NoteUtil.getFirstNoteData(AppStorage.Get('AllNoteArray'), this.selectedFolderData.uuid) 606 if (this.portraitModel == false) { 607 this.controllerShow.runJavaScript("RICH_EDITOR.setHtml('" + this.selectedNoteData?.content_text + "')") 608 } 609 // save continue data 610 let continueNote: string = JSON.stringify(this.selectedNoteData?.toNoteObject()) 611 AppStorage.SetOrCreate<string>('ContinueNote', continueNote) 612 LogUtil.info(TAG, "OperateNoteComp, set continue note success") 613 NoteUtil.refreshAll() 614 } 615 616 build() { 617 Row() { 618 Image($r('app.media.set_top')) 619 .width(24) 620 .height(24) 621 .opacity(this.CheckedNoteArray.length == 0 ? 0.4 : 1) 622 .enabled(this.CheckedNoteArray.length == 0 ? false : true) 623 .margin({ right: this.selectedFolderData.uuid == SysDefFolderUuid.RecentDeletes ? 0 : 18 }) 624 .visibility(this.selectedFolderData.uuid == SysDefFolderUuid.RecentDeletes ? Visibility.None : Visibility.Visible) 625 .onClick(() => { 626 this.CheckedNoteArray.forEach((noteItem) => { 627 noteItem.is_top = (noteItem.is_top == Top.Yes) ? Top.No : Top.Yes 628 // update note to db 629 let predicates_note = RdbStoreUtil.getRdbPredicates(TableName.NoteTable) 630 predicates_note.equalTo(NoteTableColumn.Uuid, noteItem.uuid) 631 RdbStoreUtil.update(noteItem.toNoteObject(), predicates_note, null) 632 }) 633 this.longpress = false 634 NoteUtil.unsetAllNotesChecked(this.CheckedNoteArray) 635 NoteUtil.refreshAll() 636 }) 637 Image($r('app.media.move')) 638 .width(24) 639 .height(24) 640 .opacity(this.CheckedNoteArray.length == 0 ? 0.4 : 1) 641 .enabled(this.CheckedNoteArray.length == 0 ? false : true) 642 .margin({ right: this.selectedFolderData.uuid == SysDefFolderUuid.RecentDeletes ? 0 : 18 }) 643 .visibility(this.selectedFolderData.uuid == SysDefFolderUuid.RecentDeletes ? Visibility.None : Visibility.Visible) 644 .onClick(() => { 645 this.noteDataMoveDialogCtl.open() 646 }) 647 Image($r('app.media.delete')) 648 .width(24) 649 .height(24) 650 .margin({ right: 18 }) 651 .opacity(this.CheckedNoteArray.length == 0 ? 0.4 : 1) 652 .enabled(this.CheckedNoteArray.length == 0 ? false : true) 653 .onClick(() => { 654 this.noteDataDeleteDialogCtl.open() 655 }) 656 Image($r('app.media.recover')) 657 .width(24) 658 .height(24) 659 .opacity(this.CheckedNoteArray.length == 0 ? 0.4 : 1) 660 .enabled(this.CheckedNoteArray.length == 0 ? false : true) 661 .margin({ right: this.selectedFolderData.uuid == SysDefFolderUuid.RecentDeletes ? 18 : 0 }) 662 .visibility(this.selectedFolderData.uuid == SysDefFolderUuid.RecentDeletes ? Visibility.Visible : Visibility.None) 663 .onClick(() => { 664 this.CheckedNoteArray.forEach((noteItem) => { 665 noteItem.is_deleted = Delete.No 666 noteItem.deleted_time = 0 667 let context: any = getContext(this) 668 let resource = { 669 bundleName: "com.ohos.note", 670 moduleName: "default", 671 id: $r('app.string.restore').id 672 }; 673 context.resourceManager.getString(resource, (error, value) => { 674 if (error != null) { 675 console.log("error is " + error); 676 } else { 677 prompt.showToast({ message: value, duration: 2000 }); 678 } 679 }); 680 // update note to db 681 let predicates_note = RdbStoreUtil.getRdbPredicates(TableName.NoteTable) 682 predicates_note.equalTo(NoteTableColumn.Uuid, noteItem.uuid) 683 RdbStoreUtil.update(noteItem.toNoteObject(), predicates_note, null) 684 }) 685 this.longpress = false 686 NoteUtil.unsetAllNotesChecked(this.CheckedNoteArray) 687 NoteUtil.refreshAll() 688 }) 689 Image(this.CheckedNoteArray.length == NoteUtil.getNoteDataArray(AppStorage.Get('AllNoteArray'), this.selectedFolderData.uuid) 690 .length ? $r('app.media.check_all1') : $r('app.media.check_all')) 691 .width(24) 692 .height(24) 693 .id(this.isUpdate + '') 694 .onClick(() => { 695 LogUtil.info(TAG, "select all click") 696 if (this.CheckedNoteArray.length < 697 NoteUtil.getNoteDataArray(AppStorage.Get('AllNoteArray'), this.selectedFolderData.uuid).length) { 698 NoteUtil.setAllNotesChecked(this.CheckedNoteArray, NoteUtil.getNoteDataArray(AppStorage.Get('AllNoteArray'), this.selectedFolderData.uuid)) 699 } else { 700 NoteUtil.unsetAllNotesChecked(this.CheckedNoteArray) 701 } 702 this.selectedAll = !this.selectedAll 703 this.refreshFlag = (this.refreshFlag == 0 ? 1 : 0) 704 NoteUtil.refreshAll() 705 }) 706 } 707 .width(this.selectedFolderData.uuid == SysDefFolderUuid.RecentDeletes ? 168 : 248) 708 .visibility(this.longpress && this.portraitModel == false ? Visibility.Visible : Visibility.None) 709 } 710} 711 712@Component 713export struct AddNoteComp { 714 @StorageLink('AllNoteArray') AllNoteArray: NoteData[] = AppStorage.Link('AllNoteArray') 715 @Consume('Longpress') longpress: boolean 716 @Consume('SelectedFolderData') selectedFolderData: FolderData 717 @Consume('SelectedNoteData') selectedNoteData: NoteData 718 @Consume('SectionStatus') sectionStatus: number 719 @Consume('LastSectionStatus') lastSectionStatus: number 720 @Consume('EditModel') editModel: boolean 721 @Consume('ChooseNote') chooseNote: boolean 722 @Consume('PortraitModel') portraitModel: boolean 723 controllerShow: WebviewController 724 725 build() { 726 Image($r('app.media.addNote')) 727 .width(24) 728 .height(24) 729 .margin({ right: 12 }) 730 .responseRegion({ x: -15.0, y: -15.0, width: 54, height: 54 }) 731 .onClick(() => { 732 let noteData 733 if (this.selectedFolderData.uuid == SysDefFolderUuid.AllNotes || this.selectedFolderData.uuid == SysDefFolderUuid.MyFavorites) { 734 noteData = new NoteData(0, "标题", new Date().getTime() + "", SysDefFolderUuid.UnClassified, "", "", NoteType.SysDef, Top.No, Favorite.No, Delete.No, new Date().getTime(), new Date().getTime(), 0, 0) 735 } else { 736 noteData = new NoteData(0, "标题", new Date().getTime() + "", this.selectedFolderData.uuid, "", "", NoteType.SysDef, Top.No, Favorite.No, Delete.No, new Date().getTime(), new Date().getTime(), 0, 0) 737 } 738 739 this.AllNoteArray.push(noteData) 740 RdbStoreUtil.insert(TableName.NoteTable, noteData.toNoteObject(), null) 741 LogUtil.info(TAG, 'insert new note is:' + noteData.uuid) 742 743 this.selectedNoteData = noteData 744 AppStorage.SetOrCreate<NoteData>('NewNote', noteData) 745 if (this.portraitModel == false) { 746 this.controllerShow.runJavaScript( 747 "RICH_EDITOR.setHtml('" + this.selectedNoteData?.content_text + "')" 748 ) 749 } 750 if (this.portraitModel == true) { 751 this.editModel = true 752 } 753 this.chooseNote = true 754 // save continue data 755 let continueNote: string = JSON.stringify(this.selectedNoteData?.toNoteObject()) 756 AppStorage.SetOrCreate<FolderData>('NewFolder', this.selectedFolderData) 757 AppStorage.SetOrCreate<string>('ContinueNote', continueNote) 758 LogUtil.info(TAG, "addNote, set continue note success") 759 routePage() 760 AppStorage.SetOrCreate('isUpdate', true) 761 }) 762 .visibility(this.longpress || this.selectedFolderData.uuid == SysDefFolderUuid.RecentDeletes ? Visibility.None : Visibility.Visible) 763 } 764} 765 766@Component 767export struct SearchComp { 768 @Consume('Search') search: boolean 769 @Consume('InputKeyword') inputKeyword: string 770 @Consume('Longpress') longpress: boolean 771 @State text: string = '' 772 @StorageLink('isFocusOnSearch') isFocusOnSearch: boolean = true 773 774 build() { 775 Row() { 776 Image($r('app.media.back')) 777 .width(24) 778 .height(24) 779 .responseRegion({ x: -15.0, y: -15.0, width: 54, height: 54 }) 780 .margin({ right: this.search ? 16 : 0 }) 781 .visibility(this.search ? Visibility.Visible : Visibility.None) 782 .onClick(() => { 783 focusControl.requestFocus('searchFocus') 784 this.search = false 785 // 退出键盘 786 // @ts-ignore 787 inputMethod.getController().stopInputSession(); 788 AppStorage.SetOrCreate<boolean>('Search', this.search) 789 }) 790 791 Flex({ justifyContent: FlexAlign.Start }) { 792 Image($r('app.media.search')) 793 .width(20) 794 .height(20) 795 .focusable(true) 796 .key('searchFocus') 797 .defaultFocus(true) 798 TextInput({ placeholder: $r('app.string.searchNote'), text: this.text }) 799 .backgroundColor(this.longpress ? $r("app.color.search_longpress_bgcolor_f7f8f9") : $r("app.color.color_ffffff")) 800 .caretColor($r("app.color.search_note_caret_color")) 801 .enabled(this.longpress ? false : true) 802 .padding({ left: 6, top: 1 }) 803 .onEditChange((isEditing: boolean) => { 804 // this.search = isEditing 805 }) 806 .onChange((value: string) => { 807 if (!this.longpress) { 808 LogUtil.info(TAG, "Search value: " + value) 809 this.text = value 810 this.inputKeyword = value 811 } 812 }) 813 .onClick(() => { 814 if (this.longpress) { 815 this.search = false 816 AppStorage.SetOrCreate<boolean>('Search', this.search) 817 } else { 818 this.search = true 819 AppStorage.SetOrCreate<boolean>('Search', this.search) 820 } 821 }) 822 // whether the focus is on the search input before coutinue 823 .onFocus(() => { 824 this.isFocusOnSearch = true 825 }) 826 .onBlur(() => { 827 this.isFocusOnSearch = false 828 }) 829 // key for request focus after coutinue 830 .key('searchInput') 831 .restoreId(3) 832 } 833 .backgroundColor(this.longpress ? $r("app.color.search_longpress_bgcolor_f7f8f9") : $r("app.color.color_ffffff")) 834 .height(40) 835 .opacity(this.longpress ? 0.4 : 1) 836 .padding({ left: 6, right: 12, top: 9, bottom: 9 }) 837 .borderRadius(20) 838 .border({ width: 1.5, color: $r("app.color.divider_color_e4e4e4") }) 839 .margin({ right: this.search ? 40 : 0 }) 840 } 841 } 842} 843 844@Component 845export struct OperateNoteCompForPortrait { 846 @Consume('Longpress') longpress: boolean 847 @StorageLink('CheckedNoteArray') CheckedNoteArray: NoteData[] = [] 848 @StorageLink('AllNoteArray') AllNoteArray: NoteData[] = AppStorage.Link('AllNoteArray') 849 @Consume('SelectedFolderData') selectedFolderData: FolderData 850 @Consume('RefreshFlag') @Watch('opacityChange') refreshFlag: number 851 @Consume('SelectedNoteData') selectedNoteData: NoteData 852 @Consume('PortraitModel') portraitModel: boolean 853 @State greyOpacity: boolean = false 854 @StorageLink('isUpdate') isUpdate: boolean = false 855 noteDataMoveDialogCtlBottom: CustomDialogController = new CustomDialogController({ 856 builder: NoteDataMoveDialog({ onConfirm: this.onMoveConfirm.bind(this) }), 857 alignment: DialogAlignment.Bottom, 858 autoCancel: false, 859 customStyle: true, 860 }) 861 862 aboutToDisappear() { 863 this.noteDataMoveDialogCtlBottom = null 864 this.noteDataDeleteDialogCtlBottom = null 865 } 866 867 opacityChange() { 868 if (this.CheckedNoteArray.length == 0 && this.longpress == true) { 869 this.greyOpacity = true 870 LogUtil.info(TAG, "none checked array") 871 } else { 872 this.greyOpacity = false 873 LogUtil.info(TAG, this.CheckedNoteArray.length.toString()) 874 } 875 } 876 877 onMoveConfirm(folderUuid: string) { 878 this.CheckedNoteArray.forEach((noteItem) => { 879 noteItem.folder_uuid = folderUuid 880 // update note to db 881 let predicates_note = RdbStoreUtil.getRdbPredicates(TableName.NoteTable) 882 predicates_note.equalTo(NoteTableColumn.Uuid, noteItem.uuid) 883 RdbStoreUtil.update(noteItem.toNoteObject(), predicates_note, null) 884 }) 885 this.selectedNoteData = NoteUtil.getFirstNoteData(this.AllNoteArray, this.selectedFolderData.uuid) 886 // save continue data 887 let continueNote: string = JSON.stringify(this.selectedNoteData?.toNoteObject()) 888 AppStorage.SetOrCreate<string>('ContinueNote', continueNote) 889 LogUtil.info(TAG, "onMoveConfirm, set continue note success") 890 this.longpress = false 891 this.refreshFlag = (this.refreshFlag == 0 ? 1 : 0) 892 NoteUtil.unsetAllNotesChecked(this.CheckedNoteArray) 893 NoteUtil.refreshAll() 894 } 895 896 noteDataDeleteDialogCtlBottom: CustomDialogController = new CustomDialogController({ 897 builder: DeleteDialog({ onConfirm: this.onDeleteConfirm.bind(this), multiSelect: true }), 898 alignment: DialogAlignment.Bottom, 899 autoCancel: false, 900 customStyle: true, 901 }) 902 903 onDeleteConfirm() { 904 if (this.selectedFolderData.uuid != SysDefFolderUuid.RecentDeletes) { 905 this.CheckedNoteArray.forEach((noteItem: NoteData) => { 906 noteItem.is_deleted = Delete.Yes 907 noteItem.deleted_time = new Date().getTime() 908 // update note to db 909 let predicates_note = RdbStoreUtil.getRdbPredicates(TableName.NoteTable) 910 predicates_note.equalTo(NoteTableColumn.Uuid, noteItem.uuid) 911 RdbStoreUtil.update(noteItem.toNoteObject(), predicates_note, null) 912 }) 913 } else { 914 this.CheckedNoteArray.forEach((noteItem: NoteData) => { 915 NoteUtil.removeNoteData(this.AllNoteArray, noteItem.uuid) 916 // delete note from db 917 let predicates_note = RdbStoreUtil.getRdbPredicates(TableName.NoteTable) 918 predicates_note.equalTo(NoteTableColumn.Uuid, noteItem.uuid) 919 RdbStoreUtil.delete(predicates_note, null) 920 }) 921 } 922 NoteUtil.unsetAllNotesChecked(this.CheckedNoteArray) 923 this.longpress = false 924 this.refreshFlag = (this.refreshFlag == 0 ? 1 : 0) 925 this.selectedNoteData = NoteUtil.getFirstNoteData(AppStorage.Get('AllNoteArray'), this.selectedFolderData.uuid) 926 // save continue data 927 let continueNote: string = JSON.stringify(this.selectedNoteData?.toNoteObject()) 928 AppStorage.SetOrCreate<string>('ContinueNote', continueNote) 929 LogUtil.info(TAG, "OperateNoteCompForPortrait, set continue note success") 930 NoteUtil.refreshAll() 931 } 932 933 build() { 934 Row() { 935 if (this.selectedFolderData.uuid != SysDefFolderUuid.RecentDeletes) { 936 Column() { 937 Image($r("app.media.set_top")) 938 .opacity(this.greyOpacity ? 0.4 : 1) 939 .width(24) 940 .height(24) 941 .responseRegion({ x: -15.0, y: -15.0, width: 54, height: 54 }) 942 .onClick(() => { 943 this.CheckedNoteArray.forEach((noteItem) => { 944 noteItem.is_top = (noteItem.is_top == Top.Yes) ? Top.No : Top.Yes 945 // update note to db 946 let predicates_note = RdbStoreUtil.getRdbPredicates(TableName.NoteTable) 947 predicates_note.equalTo(NoteTableColumn.Uuid, noteItem.uuid) 948 RdbStoreUtil.update(noteItem.toNoteObject(), predicates_note, null) 949 }) 950 this.longpress = false 951 this.refreshFlag = (this.refreshFlag == 0 ? 1 : 0) 952 NoteUtil.unsetAllNotesChecked(this.CheckedNoteArray) 953 NoteUtil.refreshAll() 954 }) 955 Text($r("app.string.set_top")) 956 .opacity(this.greyOpacity ? 0.4 : 1) 957 .fontSize(10) 958 .fontColor($r("app.color.set_top_font_color")) 959 .padding({ top: 5 }) 960 } 961 .width("25%") 962 .height("100%") 963 .opacity(this.greyOpacity ? 0.4 : 1) 964 .enabled(this.greyOpacity ? false : true) 965 .alignItems(HorizontalAlign.Center) 966 .justifyContent(FlexAlign.Center) 967 } 968 969 Column() { 970 Image($r('app.media.delete')) 971 .opacity(this.greyOpacity ? 0.4 : 1) 972 .width(24) 973 .height(24) 974 .responseRegion({ x: -15.0, y: -15.0, width: 54, height: 54 }) 975 .onClick(() => { 976 this.noteDataDeleteDialogCtlBottom.open() 977 AppStorage.SetOrCreate('isUpdate', true) 978 }) 979 Text($r("app.string.delete")) 980 .opacity(this.greyOpacity ? 0.4 : 1) 981 .fontSize(10) 982 .fontColor($r("app.color.delete_font_color")) 983 .padding({ top: 5 }) 984 } 985 .width(this.selectedFolderData.uuid == SysDefFolderUuid.RecentDeletes ? 120 : "25%") 986 .height("100%") 987 .opacity(this.greyOpacity ? 0.4 : 1) 988 .enabled(this.greyOpacity ? false : true) 989 .alignItems(HorizontalAlign.Center) 990 .justifyContent(FlexAlign.Center) 991 992 if (this.selectedFolderData.uuid != SysDefFolderUuid.RecentDeletes) { 993 Column() { 994 Image($r('app.media.move')) 995 .opacity(this.greyOpacity ? 0.4 : 1) 996 .width(24) 997 .height(24) 998 .responseRegion({ x: -15.0, y: -15.0, width: 54, height: 54 }) 999 .onClick(() => { 1000 this.noteDataMoveDialogCtlBottom.open() 1001 AppStorage.SetOrCreate('isUpdate', true) 1002 }) 1003 Text($r("app.string.move")) 1004 .opacity(this.greyOpacity ? 0.4 : 1) 1005 .fontSize(10) 1006 .fontColor($r("app.color.move_font_color")) 1007 .padding({ top: 5 }) 1008 } 1009 .width("25%") 1010 .height("100%") 1011 .opacity(this.greyOpacity ? 0.4 : 1) 1012 .enabled(this.greyOpacity ? false : true) 1013 .alignItems(HorizontalAlign.Center) 1014 .justifyContent(FlexAlign.Center) 1015 } 1016 1017 1018 if (this.selectedFolderData.uuid == SysDefFolderUuid.RecentDeletes) { 1019 Column() { 1020 Image($r('app.media.recover')) 1021 .width(24) 1022 .height(24) 1023 .responseRegion({ x: -15.0, y: -15.0, width: 54, height: 54 }) 1024 .onClick(() => { 1025 this.CheckedNoteArray.forEach((noteItem) => { 1026 noteItem.is_deleted = Delete.No 1027 noteItem.deleted_time = 0 1028 let context: any = getContext(this) 1029 let resource = { 1030 bundleName: "com.ohos.note", 1031 moduleName: "default", 1032 id: $r('app.string.restore').id 1033 }; 1034 context.resourceManager.getString(resource, (error, value) => { 1035 if (error != null) { 1036 console.log("error is " + error); 1037 } else { 1038 prompt.showToast({ message: value, duration: 2000 }); 1039 } 1040 }); 1041 // update note to db 1042 let predicates_note = RdbStoreUtil.getRdbPredicates(TableName.NoteTable) 1043 predicates_note.equalTo(NoteTableColumn.Uuid, noteItem.uuid) 1044 RdbStoreUtil.update(noteItem.toNoteObject(), predicates_note, null) 1045 }) 1046 this.longpress = false 1047 NoteUtil.unsetAllNotesChecked(this.CheckedNoteArray) 1048 this.refreshFlag = (this.refreshFlag == 0 ? 1 : 0) 1049 AppStorage.SetOrCreate('isUpdate', true) 1050 NoteUtil.refreshAll() 1051 }) 1052 Text($r("app.string.recover")) 1053 .fontSize(10) 1054 .fontColor($r("app.color.recover_font_color")) 1055 .padding({ top: 5 }) 1056 } 1057 .width(this.selectedFolderData.uuid == SysDefFolderUuid.RecentDeletes ? 120 : "25%") 1058 .height("100%") 1059 .opacity(this.greyOpacity ? 0.4 : 1) 1060 .enabled(this.greyOpacity ? false : true) 1061 .alignItems(HorizontalAlign.Center) 1062 .justifyContent(FlexAlign.Center) 1063 } 1064 1065 Column() { 1066 Image($r('app.media.check_all')) 1067 .width(24) 1068 .height(24) 1069 .responseRegion({ x: -15.0, y: -15.0, width: 54, height: 54 }) 1070 .id(this.isUpdate + '') 1071 .onClick(() => { 1072 if (this.CheckedNoteArray.length < 1073 NoteUtil.getNoteDataArray(AppStorage.Get('AllNoteArray'), this.selectedFolderData.uuid) 1074 .length) { 1075 NoteUtil.setAllNotesChecked(this.CheckedNoteArray, NoteUtil.getNoteDataArray(AppStorage.Get('AllNoteArray'), this.selectedFolderData.uuid)) 1076 } else { 1077 NoteUtil.unsetAllNotesChecked(this.CheckedNoteArray) 1078 } 1079 this.refreshFlag = (this.refreshFlag == 0 ? 1 : 0) 1080 NoteUtil.refreshAll() 1081 }) 1082 Text($r("app.string.check_all")) 1083 .fontSize(10) 1084 .fontColor($r("app.color.check_all_font_color")) 1085 .padding({ top: 5 }) 1086 } 1087 .width(this.selectedFolderData.uuid == SysDefFolderUuid.RecentDeletes ? 120 : "25%") 1088 .height("100%") 1089 .alignItems(HorizontalAlign.Center) 1090 .justifyContent(FlexAlign.Center) 1091 } 1092 .justifyContent(FlexAlign.Center) 1093 .width("100%") 1094 .height(56) 1095 .visibility(this.longpress && this.portraitModel == true ? Visibility.Visible : Visibility.None) 1096 } 1097} 1098