Skip to content

Commit

Permalink
Improve item details collection view notes section performance
Browse files Browse the repository at this point in the history
  • Loading branch information
mvasilak committed Oct 31, 2024
1 parent f5a4097 commit 3cdd33d
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ enum ItemDetailAction {
case deleteAttachmentFile(Attachment)
case deleteAttachment(Attachment)
case deleteCreator(String)
case deleteNote(Note)
case deleteNote(key: String)
case deleteTag(Tag)
case endEditing
case loadInitialData
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,8 @@ struct ItemDetailActionHandler: ViewModelActionHandler, BackgroundDbProcessingAc
case .deleteTag(let tag):
self.delete(tag: tag, in: viewModel)

case .deleteNote(let note):
self.delete(note: note, in: viewModel)
case .deleteNote(let key):
self.deleteNote(key: key, in: viewModel)

case .deleteAttachment(let attachment):
self.delete(attachment: attachment, in: viewModel)
Expand Down Expand Up @@ -370,10 +370,10 @@ struct ItemDetailActionHandler: ViewModelActionHandler, BackgroundDbProcessingAc
}
}

private func delete(note: Note, in viewModel: ViewModel<ItemDetailActionHandler>) {
guard viewModel.state.notes.contains(note) else { return }
self.trashItem(key: note.key, reloadType: .section(.notes), in: viewModel) { state in
guard let index = viewModel.state.notes.firstIndex(of: note) else { return }
private func deleteNote(key: String, in viewModel: ViewModel<ItemDetailActionHandler>) {
guard viewModel.state.notes.contains(where: { $0.key == key }) else { return }
trashItem(key: key, reloadType: .section(.notes), in: viewModel) { state in
guard let index = viewModel.state.notes.firstIndex(where: { $0.key == key }) else { return }
state.notes.remove(at: index)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ final class ItemDetailCollectionViewHandler: NSObject {
enum Action {
case openCreatorCreation
case openCreatorEditor(ItemDetailState.Creator)
case openNoteEditor(Note?)
case openNoteEditor(key: String?)
case openTagPicker
case openTypePicker
case openFilePicker
Expand Down Expand Up @@ -61,7 +61,7 @@ final class ItemDetailCollectionViewHandler: NSObject {
case dateAdded(Date)
case dateModified(Date)
case field(key: String, multiline: Bool)
case note(note: Note, isProcessing: Bool)
case note(key: String, title: String, isProcessing: Bool)
case tag(id: UUID, tag: Tag, isProcessing: Bool)
case title
case type(String)
Expand Down Expand Up @@ -227,8 +227,8 @@ final class ItemDetailCollectionViewHandler: NSObject {
}
return collectionView.dequeueConfiguredReusableCell(using: fieldEditRegistration, for: indexPath, item: (field, titleWidth))

case .note(let note, let isProcessing):
return collectionView.dequeueConfiguredReusableCell(using: noteRegistration, for: indexPath, item: (note, isProcessing))
case .note(let key, let title, let isProcessing):
return collectionView.dequeueConfiguredReusableCell(using: noteRegistration, for: indexPath, item: (key, title, isProcessing))

case .tag(_, let tag, let isProcessing):
return collectionView.dequeueConfiguredReusableCell(using: tagRegistration, for: indexPath, item: (tag, isProcessing))
Expand Down Expand Up @@ -356,7 +356,7 @@ final class ItemDetailCollectionViewHandler: NSObject {
case .attachment(_, let type) where type != .disabled:
title = L10n.moveToTrash

case .note(_, let isProcessing) where !isProcessing:
case .note(_, _, let isProcessing) where !isProcessing:
title = L10n.moveToTrash

case .tag(_, _, let isProcessing) where !isProcessing:
Expand Down Expand Up @@ -389,8 +389,8 @@ final class ItemDetailCollectionViewHandler: NSObject {
case .attachment(let attachment, _):
self.viewModel.process(action: .deleteAttachment(attachment))

case .note(let note, _):
self.viewModel.process(action: .deleteNote(note))
case .note(let key, _, _):
self.viewModel.process(action: .deleteNote(key: key))

case .title, .abstract, .addAttachment, .addCreator, .addNote, .addTag, .dateAdded, .dateModified, .type, .field:
break
Expand Down Expand Up @@ -620,7 +620,7 @@ final class ItemDetailCollectionViewHandler: NSObject {

for _row in dataSource.snapshot().itemIdentifiers {
switch _row {
case .note(let note, _) where note.key == itemKey:
case .note(let key, _, _) where key == itemKey:
row = _row

case .attachment(let attachment, _) where attachment.key == itemKey:
Expand Down Expand Up @@ -674,7 +674,7 @@ final class ItemDetailCollectionViewHandler: NSObject {
case .notes:
let notes: [Row] = state.notes.map({ note in
let isProcessing = state.backgroundProcessedItems.contains(note.key)
return .note(note: note, isProcessing: isProcessing)
return .note(key: note.key, title: note.title, isProcessing: isProcessing)
})
if state.library.metadataEditable {
return notes + [.addNote]
Expand Down Expand Up @@ -836,10 +836,10 @@ final class ItemDetailCollectionViewHandler: NSObject {
}
}()

private lazy var noteRegistration: UICollectionView.CellRegistration<ItemDetailNoteCell, (Note, Bool)> = {
private lazy var noteRegistration: UICollectionView.CellRegistration<ItemDetailNoteCell, (key: String, title: String, isProcessing: Bool)> = {
return UICollectionView.CellRegistration { [weak self] cell, indexPath, data in
guard let self else { return }
cell.contentConfiguration = ItemDetailNoteCell.ContentConfiguration(note: data.0, isProcessing: data.1, layoutMargins: layoutMargins(for: indexPath, self: self))
cell.contentConfiguration = ItemDetailNoteCell.ContentConfiguration(title: data.title, isProcessing: data.isProcessing, layoutMargins: layoutMargins(for: indexPath, self: self))
}
}()

Expand Down Expand Up @@ -878,7 +878,7 @@ extension ItemDetailCollectionViewHandler: UICollectionViewDelegate {

switch row {
case .addNote:
observer.on(.next(.openNoteEditor(nil)))
observer.on(.next(.openNoteEditor(key: nil)))

case .addAttachment:
observer.on(.next(.openFilePicker))
Expand All @@ -901,9 +901,9 @@ extension ItemDetailCollectionViewHandler: UICollectionViewDelegate {
guard viewModel.state.isEditing else { return }
observer.on(.next(.openCreatorEditor(creator)))

case .note(let note, let isProcessing):
case .note(let key, let title, let isProcessing):
guard !isProcessing else { return }
observer.on(.next(.openNoteEditor(note)))
observer.on(.next(.openNoteEditor(key: key)))

case .type:
guard viewModel.state.isEditing && !viewModel.state.data.isAttachment else { return }
Expand Down Expand Up @@ -964,8 +964,8 @@ extension ItemDetailCollectionViewHandler: UICollectionViewDelegate {
case .tag(_, let tag, _):
menu = createContextMenu(for: tag)

case .note(let note, _):
menu = createContextMenu(for: note)
case .note(let key, _, _):
menu = createContextMenuForNote(key: key)

default:
return nil
Expand Down Expand Up @@ -995,10 +995,10 @@ extension ItemDetailCollectionViewHandler: UICollectionViewDelegate {
return UIMenu(title: "", children: actions)
}

func createContextMenu(for note: Note) -> UIMenu? {
func createContextMenuForNote(key: String) -> UIMenu? {
var actions: [UIAction] = []
actions.append(UIAction(title: L10n.moveToTrash, image: UIImage(systemName: "trash"), attributes: .destructive) { [weak self] _ in
self?.viewModel.process(action: .deleteNote(note))
self?.viewModel.process(action: .deleteNote(key: key))
})
return UIMenu(title: "", children: actions)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import UIKit

final class ItemDetailNoteCell: UICollectionViewListCell {
struct ContentConfiguration: UIContentConfiguration {
let note: Note
let title: String
let isProcessing: Bool
let layoutMargins: UIEdgeInsets

Expand Down Expand Up @@ -51,7 +51,7 @@ final class ItemDetailNoteCell: UICollectionViewListCell {

private func apply(configuration: ContentConfiguration) {
self.contentView.layoutMargins = configuration.layoutMargins
self.contentView.setup(with: configuration.note, isProcessing: configuration.isProcessing)
self.contentView.setup(with: configuration.title, isProcessing: configuration.isProcessing)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ class ItemDetailNoteContentView: UIView {
self.heightAnchor.constraint(greaterThanOrEqualToConstant: ItemDetailLayout.minCellHeight).isActive = true
}

func setup(with note: Note, isProcessing: Bool) {
func setup(with title: String, isProcessing: Bool) {
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.minimumLineHeight = ItemDetailLayout.lineHeight
paragraphStyle.maximumLineHeight = ItemDetailLayout.lineHeight
let attributedString = NSAttributedString(string: note.title, attributes: [.font: UIFont.preferredFont(forTextStyle: .body), .paragraphStyle: paragraphStyle])
let attributedString = NSAttributedString(string: title, attributes: [.font: UIFont.preferredFont(forTextStyle: .body), .paragraphStyle: paragraphStyle])
self.label.attributedText = attributedString
self.label.textColor = isProcessing ? .systemGray2 : .label

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,14 +175,14 @@ final class ItemDetailViewController: UIViewController {
self?.viewModel.process(action: .addAttachments(urls))
})

case .openNoteEditor(let note):
case .openNoteEditor(let key):
let library = viewModel.state.library
var kind: NoteEditorKind = .itemCreation(parentKey: viewModel.state.key)
var text: String = ""
var tags: [Tag] = []
var title: String?
let parentTitleData = NoteEditorState.TitleData(type: viewModel.state.data.type, title: viewModel.state.data.title)
if let note {
if let note = viewModel.state.notes.first(where: { $0.key == key }) {
if library.metadataEditable {
kind = .edit(key: note.key)
} else {
Expand Down

0 comments on commit 3cdd33d

Please sign in to comment.