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 FolderData from '@ohos/utils/src/main/ets/default/model/databaseModel/FolderData' 17import NoteData from '@ohos/utils/src/main/ets/default/model/databaseModel/NoteData' 18import { 19 SysDefFolderUuid, 20 TableName, 21 FolderType, 22 FolderTableColumn, 23 NoteTableColumn, 24 Delete, 25 DeleteFileType 26} from '@ohos/utils/src/main/ets/default/model/databaseModel/EnumData' 27import { NewOrEditFolderDialog, DeleteDialog } from './CusDialogComp' 28import RdbStoreUtil from '@ohos/utils/src/main/ets/default/baseUtil/RdbStoreUtil' 29import FolderUtil from '@ohos/utils/src/main/ets/default/baseUtil/FolderUtil' 30import NoteUtil from '@ohos/utils/src/main/ets/default/baseUtil/NoteUtil' 31import { LogUtil } from '@ohos/utils/src/main/ets/default/baseUtil/LogUtil' 32 33// Folder list component 34@Component 35export struct FolderListComp { 36 @StorageLink('AllFolderArray') AllFolderArray: FolderData[] = AppStorage.Link('AllFolderArray') 37 @Consume('SectionStatus') sectionStatus: number 38 @Consume('ExpandStatus') expandStatus: boolean // 笔记本折叠展开状态 39 @StorageLink('breakPoint') breakPoints: string = 'lg' 40 controllerShow: WebviewController 41 TAG = "FolderListComp" 42 @Consume('AsideWidth') asideWidth: number 43 44 build() { 45 Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.SpaceBetween }) { 46 Column() { 47 Column() { 48 Image($r("app.media.suojin")) 49 .height(24) 50 .width(24) 51 .responseRegion({ x: -15.0, y: -15.0, width: 54, height: 54 }) 52 .onClick(() => { 53 if (this.breakPoints == 'sm' || this.breakPoints == 'md') { 54 animateTo({ duration: 200 }, () => { 55 this.expandStatus = !this.expandStatus 56 }) 57 } else { 58 this.asideWidth = 0 59 this.sectionStatus = (this.sectionStatus == 3 ? 2 : 3) 60 // save continue data 61 AppStorage.SetOrCreate<number>('ContinueSection', this.sectionStatus) 62 LogUtil.info(this.TAG, "FolderListComp, set continue section success") 63 } 64 }) 65 } 66 .alignItems(HorizontalAlign.Start) 67 .width("100%") 68 .margin({ top: 28 }) 69 .padding({ left: 24 }) 70 .flexGrow(1) 71 72 NoteAndCreateComp() 73 // center 74 List() { 75 ForEach(this.AllFolderArray, (folderItem: FolderData) => { 76 ListItem() { 77 if (!FolderUtil.isBottomFixedFolder(folderItem)) { 78 FolderItemComp({ folderItem: folderItem, controllerShow: this.controllerShow }) 79 } 80 } 81 }, folderItem => folderItem.name.toString()) 82 } 83 .width('100%') 84 .height(500) 85 .margin({ bottom: 120 }) 86 .padding({ left: 12, right: 12 }) 87 .flexGrow(1) 88 } 89 90 91 Column() { 92 FolderItemComp({ 93 folderItem: FolderUtil.getFolderData(AppStorage.Get('AllFolderArray'), SysDefFolderUuid.MyFavorites), 94 controllerShow: this.controllerShow 95 }) 96 FolderItemComp({ 97 folderItem: FolderUtil.getFolderData(AppStorage.Get('AllFolderArray'), SysDefFolderUuid.RecentDeletes), 98 controllerShow: this.controllerShow 99 }) 100 } 101 .backgroundColor($r("app.color.folderlist_bgcolor_f1f3f5")) 102 .flexGrow(0) 103 .width("100%") 104 .padding({ left: 12, right: 12, bottom: 24 }) 105 } 106 .height("100%") 107 .backgroundColor($r('app.color.folder_color_d6d6d6')) 108 .backgroundBlurStyle(BlurStyle.Thick) 109 } 110 111 aboutToAppear(): void { 112 LogUtil.info(this.TAG, "aboutToAppear") 113 } 114 115 aboutToDisappear(): void { 116 LogUtil.info(this.TAG, "aboutToDisappear") 117 } 118} 119 120@Component 121export struct NoteAndCreateComp { 122 @StorageLink('AllFolderArray') AllFolderArray: FolderData[] = AppStorage.Link('AllFolderArray') 123 @Consume('SelectedColor') selectedColor: string 124 @Consume('PortraitModel') portraitModel: boolean 125 folderCreateDialogCtl: CustomDialogController = new CustomDialogController({ 126 builder: NewOrEditFolderDialog({ confirm: this.onCreateConfirm.bind(this), dialogType: 0 }), 127 alignment: DialogAlignment.Center, 128 autoCancel: false, 129 customStyle: true, 130 }) 131 folderCreateDialogCtlBottom: CustomDialogController = new CustomDialogController({ 132 builder: NewOrEditFolderDialog({ confirm: this.onCreateConfirm.bind(this), dialogType: 0 }), 133 alignment: DialogAlignment.Bottom, 134 autoCancel: false, 135 customStyle: true, 136 }) 137 138 aboutToDisappear() { 139 this.folderCreateDialogCtl = null 140 this.folderCreateDialogCtlBottom = null 141 } 142 143 onCreateConfirm(color: string, name: string) { 144 let folderData = new FolderData(0, name, new Date().getTime() + "", color, FolderType.CusDef, Delete.No, new Date().getTime(), new Date().getTime()) // 新的的笔记本都是自定义类型 type为1 145 this.AllFolderArray.push(folderData) 146 // insert folder to db 147 RdbStoreUtil.insert(TableName.FolderTable, folderData.toFolderObject(), null) 148 AppStorage.SetOrCreate('isUpdate', true) 149 } 150 151 build() { 152 Flex({ alignItems: ItemAlign.Center, justifyContent: FlexAlign.SpaceBetween }) { 153 Row() { 154 Text($r("app.string.note")) 155 .fontSize(20) 156 .fontWeight(FontWeight.Bold) 157 }.width(102) 158 159 Row() { 160 Text($r("app.string.create")) 161 .fontSize(14) 162 .fontColor($r("app.color.text_color_f86d05")) 163 .onClick(() => { 164 this.selectedColor = "#e84026" // 新建的时候选中第一个颜色 165 if (this.portraitModel) { 166 this.folderCreateDialogCtlBottom.open() 167 } else { 168 this.folderCreateDialogCtl.open() 169 } 170 }).padding({ right: 0 }) 171 }.width(50) 172 }.width("100%") 173 .margin({ top: 8 }) 174 .padding({ left: 24 }) 175 .height(56) 176 } 177} 178 179@Component 180struct FolderItemComp { 181 @State folderItem: FolderData = new FolderData(0, "", new Date().getTime() + "", "", FolderType.CusDef, Delete.No, new Date().getTime(), new Date().getTime()) 182 @StorageLink('AllNoteArray') AllNoteArray: NoteData[] = [] 183 @StorageLink('AllFolderArray') AllFolderArray: FolderData[] = [] 184 @StorageLink('CheckedNoteArray') CheckedNoteArray: NoteData[] = [] 185 @Consume('SelectedFolderData') selectedFolderData: FolderData 186 @Consume('SelectedNoteData') selectedNoteData: NoteData 187 @Consume('RefreshFlag') refreshFlag: number 188 @Consume('Longpress') longpress: boolean 189 @Consume('SelectedColor') selectedColor: string 190 @Consume('PortraitModel') portraitModel: boolean 191 controllerShow: WebviewController 192 @State isLongPress: boolean = false 193 TAG = "FolderListComp" 194 @StorageLink('isUpdate') isUpdate: boolean = false 195 // Folder Edit Dialog 196 folderEditDialogCtl: CustomDialogController = new CustomDialogController({ 197 builder: NewOrEditFolderDialog({ 198 editFolderUuid: this.folderItem.uuid, 199 confirm: this.onEditConfirm.bind(this), 200 dialogType: 1 201 }), 202 alignment: DialogAlignment.Center, 203 autoCancel: false, 204 customStyle: true, 205 }) 206 // Folder Edit Dialog for portrait model 207 folderEditDialogCtlBottom: CustomDialogController = new CustomDialogController({ 208 builder: NewOrEditFolderDialog({ 209 editFolderUuid: this.folderItem.uuid, 210 confirm: this.onEditConfirm.bind(this), 211 dialogType: 1 212 }), 213 alignment: DialogAlignment.Bottom, 214 autoCancel: false, 215 customStyle: true, 216 }) 217 218 aboutToDisappear() { 219 this.folderEditDialogCtl = null 220 this.folderEditDialogCtlBottom = null 221 this.folderDeleteDialogCtl = null 222 this.folderDeleteDialogCtlBottom = null 223 this.folderCreateDialogCtl = null 224 this.folderCreateDialogCtlBottom = null 225 } 226 227 // Folder Edit Callback 228 onEditConfirm(color: string, name: string) { 229 this.folderItem.color = color 230 this.folderItem.name = name 231 this.folderItem.folder_type = FolderType.CusDef 232 // update folder to db 233 let predicates_folder = RdbStoreUtil.getRdbPredicates(TableName.FolderTable) 234 predicates_folder.equalTo(FolderTableColumn.Uuid, this.folderItem.uuid) 235 RdbStoreUtil.update(this.folderItem.toFolderObject(), predicates_folder, null) 236 this.isUpdate = true 237 } 238 // Folder Delete Dialog 239 folderDeleteDialogCtl: CustomDialogController = new CustomDialogController({ 240 builder: DeleteDialog({ onConfirm: this.onDeleteConfirm.bind(this), deleteFileType: DeleteFileType.FolderData }), 241 alignment: DialogAlignment.Center, 242 autoCancel: false, 243 customStyle: true, 244 }) 245 // Folder Delete Dialog for portrait model 246 folderDeleteDialogCtlBottom: CustomDialogController = new CustomDialogController({ 247 builder: DeleteDialog({ onConfirm: this.onDeleteConfirm.bind(this), deleteFileType: DeleteFileType.FolderData }), 248 alignment: DialogAlignment.Bottom, 249 autoCancel: false, 250 customStyle: true, 251 }) 252 // Folder Delete Callback 253 onDeleteConfirm() { 254 let currentFolder = FolderUtil.getFolderData(this.AllFolderArray, this.folderItem.uuid) 255 let index = this.AllFolderArray.indexOf(currentFolder) 256 let currentNoteDataArray = NoteUtil.getNoteDataArray(AppStorage.Get('AllNoteArray'), this.folderItem.uuid) 257 let deleteNoteDataArray = NoteUtil.getNoteDataArray(AppStorage.Get('AllNoteArray'), 'sys_def_recentDeletes_uuid') 258 if (index > -1) { 259 this.AllFolderArray.splice(index, 1) 260 if (deleteNoteDataArray.length != 0) { 261 deleteNoteDataArray.forEach((noteItem: NoteData) => { 262 let folderData: FolderData = FolderUtil.getFolderData(this.AllFolderArray, noteItem.folder_uuid) 263 if (folderData == undefined) { 264 noteItem.folder_uuid = SysDefFolderUuid.UnClassified 265 // update note to db 266 let predicates_note = RdbStoreUtil.getRdbPredicates(TableName.NoteTable) 267 predicates_note.equalTo(NoteTableColumn.Uuid, noteItem.uuid) 268 RdbStoreUtil.update(noteItem.toNoteObject(), predicates_note, null) 269 } 270 }) 271 } 272 if (currentNoteDataArray.length != 0) { 273 currentNoteDataArray.forEach((noteItem: NoteData) => { 274 noteItem.is_deleted = Delete.Yes 275 noteItem.folder_uuid = SysDefFolderUuid.UnClassified 276 noteItem.deleted_time = new Date().getTime() 277 // update note to db 278 let predicates_note = RdbStoreUtil.getRdbPredicates(TableName.NoteTable) 279 predicates_note.equalTo(NoteTableColumn.Uuid, noteItem.uuid) 280 RdbStoreUtil.update(noteItem.toNoteObject(), predicates_note, null) 281 }) 282 } 283 // delete folder from db 284 let predicates_folder = RdbStoreUtil.getRdbPredicates(TableName.FolderTable) 285 predicates_folder.equalTo(FolderTableColumn.Uuid, this.folderItem.uuid) 286 RdbStoreUtil.delete(predicates_folder, null) 287 // update selectedFolderData and selectedNoteData 288 this.selectedFolderData = FolderUtil.getFolderData(this.AllFolderArray, SysDefFolderUuid.AllNotes) 289 this.selectedNoteData = NoteUtil.getFirstNoteData(this.AllNoteArray, SysDefFolderUuid.AllNotes) 290 if (!this.selectedNoteData) { 291 return 292 } 293 // 刷新web界面 294 if (this.portraitModel == false) { 295 this.controllerShow.runJavaScript( 296 "RICH_EDITOR.setHtml('" + this.selectedNoteData.content_text + "')" 297 ) 298 } 299 // save continue data 300 let continueNote: string = JSON.stringify(this.selectedNoteData.toNoteObject()) 301 AppStorage.SetOrCreate<string>('ContinueNote', continueNote) 302 LogUtil.info(this.TAG, "onDeleteConfirm, set continue note success") 303 } 304 this.isUpdate = true 305 } 306 // Folder Create Dialog 307 folderCreateDialogCtl: CustomDialogController = new CustomDialogController({ 308 builder: NewOrEditFolderDialog({ confirm: this.onCreateConfirm.bind(this), dialogType: 0 }), 309 alignment: DialogAlignment.Center, 310 autoCancel: false, 311 customStyle: true, 312 }) 313 // Folder Create Dialog for portrait model 314 folderCreateDialogCtlBottom: CustomDialogController = new CustomDialogController({ 315 builder: NewOrEditFolderDialog({ confirm: this.onCreateConfirm.bind(this), dialogType: 0 }), 316 alignment: DialogAlignment.Bottom, 317 autoCancel: false, 318 customStyle: true, 319 }) 320 // Folder Create Callback 321 onCreateConfirm(color: string, name: string) { 322 let folderData = new FolderData(0, name, new Date().getTime() + "", color, FolderType.CusDef, Delete.No, new Date().getTime(), new Date().getTime()) // 新的的笔记本都是自定义类型 type为1 323 this.AllFolderArray.push(folderData) 324 // insert folder to db 325 RdbStoreUtil.insert(TableName.FolderTable, folderData.toFolderObject(), null) 326 this.isUpdate = true 327 } 328 329 @Builder menuBuilder() { 330 Column({ space: 1 }) { 331 Text($r("app.string.editFolder")) 332 .width(124) 333 .height(48) 334 .padding({ top: 13, bottom: 13 }) 335 .fontSize(16) 336 .fontColor($r("app.color.folder_color_182431")) 337 .onClick(() => { 338 this.selectedColor = this.folderItem.color 339 if (this.portraitModel) { 340 this.folderEditDialogCtlBottom.open() 341 } else { 342 this.folderEditDialogCtl.open() 343 } 344 ContextMenu.close() 345 }) 346 Divider() 347 .color($r("app.color.divider_color_e4e4e4")) 348 .strokeWidth(1) 349 Text($r("app.string.deleteFolder")) 350 .width(124) 351 .height(48) 352 .padding({ top: 13, bottom: 14 }) 353 .fontSize(16) 354 .fontColor($r("app.color.folder_color_182431")) 355 .onClick(() => { 356 if (this.portraitModel) { 357 this.folderDeleteDialogCtlBottom.open() 358 } else { 359 this.folderDeleteDialogCtl.open() 360 } 361 ContextMenu.close() 362 }) 363 Divider() 364 .color($r("app.color.divider_color_e4e4e4")) 365 .strokeWidth(1) 366 Text($r("app.string.createFolder")) 367 .width(124) 368 .height(48) 369 .padding({ top: 13, bottom: 15 }) 370 .fontSize(16) 371 .fontColor($r("app.color.folder_color_182431")) 372 .onClick(() => { 373 this.selectedColor = "#e84026" // 新建的时候选中第一个颜色 374 if (this.portraitModel) { 375 this.folderCreateDialogCtlBottom.open() 376 } else { 377 this.folderCreateDialogCtl.open() 378 } 379 ContextMenu.close() 380 }) 381 } 382 .width(156) 383 .height(154) 384 .padding({ top: 4, bottom: 4, left: 16, right: 16 }) 385 .borderRadius(16) 386 .backgroundColor($r("app.color.press_folder_bg_color")) 387 } 388 389 build() { 390 Flex() { 391 if (this.folderItem?.folder_type == FolderType.CusDef) { 392 Flex({ alignItems: ItemAlign.Center, wrap: FlexWrap.NoWrap, justifyContent: FlexAlign.SpaceBetween }) { 393 Row() { 394 Image(FolderUtil.getFolderIcon(this.folderItem.uuid)) 395 .id(this.isUpdate + '') 396 .objectFit(ImageFit.Fill) 397 .width(24) 398 .height(24) 399 .fillColor(FolderUtil.getFolderIconColor(this.AllFolderArray, this.folderItem.uuid, this.selectedFolderData.uuid == this.folderItem.uuid)) 400 .margin({ right: 16 }) 401 Text(FolderUtil.getFolderText(this.folderItem)) 402 .id(this.isUpdate + '') 403 .fontWeight(FontWeight.Medium) 404 .fontSize(16) 405 .textAlign(TextAlign.Center) 406 .maxLines(1) 407 .textOverflow({ overflow: TextOverflow.Ellipsis }) 408 .flexShrink(1) 409 .fontColor(FolderUtil.getFolderTextColor(this.selectedFolderData.uuid == this.folderItem.uuid)) 410 Text(JSON.stringify(this.refreshFlag)) 411 .visibility(Visibility.None) // 用于强制刷新使用 412 }.width(118) 413 414 Text(FolderUtil.getNoteCount(AppStorage.Get('AllNoteArray'), this.folderItem.uuid).toString()) 415 .id(this.isUpdate + '') 416 .fontWeight(FontWeight.Regular) 417 .fontSize(14) 418 .textAlign(TextAlign.Center) 419 } 420 .width('100%') 421 .borderRadius(12) 422 .height(56) 423 .padding({ left: 12, right: 12 }) 424 .backgroundColor(this.isLongPress ? $r("app.color.folder_color_19182431") : this.selectedFolderData.uuid == this.folderItem.uuid 425 ? $r("app.color.folder_color_ffffff") : "#00FFFFFF") 426 .bindContextMenu(this.menuBuilder, ResponseType.LongPress) 427 .bindContextMenu(this.menuBuilder, ResponseType.RightClick) 428 .onClick(() => { 429 if (this.longpress) { 430 this.longpress = false 431 NoteUtil.unsetAllNotesChecked(this.CheckedNoteArray) 432 } else { 433 this.selectedFolderData = this.folderItem 434 this.selectedNoteData = NoteUtil.getFirstNoteData(AppStorage.Get('AllNoteArray'), this.folderItem.uuid) 435 if (!this.selectedNoteData) { 436 return 437 } 438 // 刷新web界面 439 if (this.portraitModel == false) { 440 this.controllerShow.runJavaScript( 441 "RICH_EDITOR.setHtml('" + this.selectedNoteData.content_text + "')" 442 ) 443 } 444 // save continue data 445 let continueNote: string = JSON.stringify(this.selectedNoteData.toNoteObject()) 446 AppStorage.SetOrCreate<string>('ContinueNote', continueNote) 447 AppStorage.SetOrCreate('ContinueSection', 3) 448 LogUtil.info(this.TAG, "FolderItemComp, set continue note success") 449 } 450 NoteUtil.refreshAll() 451 }) 452 } else { 453 Flex({ alignItems: ItemAlign.Center, wrap: FlexWrap.NoWrap, justifyContent: FlexAlign.SpaceBetween }) { 454 Row() { 455 Image(FolderUtil.getFolderIcon(this.folderItem.uuid)) 456 .id(this.isUpdate + '') 457 .objectFit(ImageFit.Fill) 458 .width(24) 459 .height(24) 460 .fillColor(this.isUpdate ? FolderUtil.getFolderIconColor(this.AllFolderArray, this.folderItem.uuid, this.selectedFolderData.uuid == this.folderItem.uuid) : FolderUtil.getFolderIconColor(this.AllFolderArray, this.folderItem.uuid, this.selectedFolderData.uuid == this.folderItem.uuid)) 461 .margin({ right: 16 }) 462 Text(FolderUtil.getFolderText(this.folderItem)) 463 .id(this.isUpdate + '') 464 .fontWeight(FontWeight.Medium) 465 .fontSize(16) 466 .textAlign(TextAlign.Center) 467 .maxLines(1) 468 .textOverflow({ overflow: TextOverflow.Ellipsis }) 469 .flexShrink(1) 470 .fontColor(FolderUtil.getFolderTextColor(this.selectedFolderData.uuid == this.folderItem.uuid)) 471 Text(JSON.stringify(this.refreshFlag)) 472 .visibility(Visibility.None) // 用于强制刷新使用 473 }.width(118) 474 475 Text(FolderUtil.getNoteCount(AppStorage.Get('AllNoteArray'), this.folderItem.uuid).toString()) 476 .id(this.isUpdate + '') 477 .fontWeight(FontWeight.Regular) 478 .fontSize(14) 479 .textAlign(TextAlign.Center) 480 } 481 .width('100%') 482 .borderRadius(12) 483 .height(56) 484 .padding({ left: 12, right: 12 }) 485 .backgroundColor(this.isLongPress ? $r("app.color.folder_color_19182431") : this.selectedFolderData.uuid == this.folderItem.uuid 486 ? $r("app.color.folder_color_ffffff") : "#00FFFFFF") 487 .onClick(() => { 488 if (this.longpress) { 489 this.longpress = false 490 NoteUtil.unsetAllNotesChecked(this.CheckedNoteArray) 491 } else { 492 this.selectedFolderData = this.folderItem 493 this.selectedNoteData = NoteUtil.getFirstNoteData(AppStorage.Get('AllNoteArray'), this.folderItem.uuid) 494 if (!this.selectedNoteData) { 495 return 496 } 497 // 刷新web界面 498 if (this.portraitModel == false) { 499 this.controllerShow.runJavaScript( 500 "RICH_EDITOR.setHtml('" + this.selectedNoteData.content_text + "')" 501 ) 502 } 503 // save continue data 504 let continueNote: string = JSON.stringify(this.selectedNoteData.toNoteObject()) 505 AppStorage.SetOrCreate<string>('ContinueNote', continueNote) 506 AppStorage.SetOrCreate('ContinueSection', 3) 507 LogUtil.info(this.TAG, "FolderItemComp, set continue note success") 508 } 509 NoteUtil.refreshAll() 510 }) 511 } 512 } 513 .width('100%') 514 .height(56) 515 .parallelGesture( 516 GestureGroup(GestureMode.Exclusive, 517 LongPressGesture() 518 .onAction(() => { 519 this.isLongPress = true 520 this.refreshFlag = (this.refreshFlag == 0 ? 1 : 0) 521 }) 522 .onActionEnd(() => { 523 this.isLongPress = false 524 this.refreshFlag = (this.refreshFlag == 0 ? 1 : 0) 525 }) 526 ) 527 ) 528 } 529}