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