Skip to content

Commit

Permalink
Implemented new PSPDFKit menu API (#715)
Browse files Browse the repository at this point in the history
Implemented PSPDFKit new menu API, fixed annotation creation bug
  • Loading branch information
michalrentka authored Jul 4, 2023
1 parent b10cd72 commit 75274ff
Show file tree
Hide file tree
Showing 7 changed files with 224 additions and 98 deletions.
2 changes: 1 addition & 1 deletion Zotero/Controllers/AnnotationConverter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ struct AnnotationConverter {
}
}

if let blendMode = blendMode {
if let blendMode {
annotation.blendMode = blendMode
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ struct CreateAnnotationsDbRequest: DbRequest {
}

private func addFields(for annotation: Annotation, to item: RItem, database: Realm) {
for field in FieldKeys.Item.Annotation.fields(for: annotation.type) {
for field in FieldKeys.Item.Annotation.allFields(for: annotation.type) {
let rField = RItemField()
rField.key = field.key
rField.baseKey = field.baseKey
Expand Down
2 changes: 1 addition & 1 deletion Zotero/Models/API/ItemResponse.swift
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ struct ItemResponse {
throw SchemaError.invalidValue(value: rawType, field: FieldKeys.Item.Annotation.type, key: key)
}

let mandatoryFields = FieldKeys.Item.Annotation.fields(for: type)
let mandatoryFields = FieldKeys.Item.Annotation.mandatoryApiFields(for: type)
for field in mandatoryFields {
guard let value = fields[field] else {
throw SchemaError.missingField(key: key, field: field.key, itemType: itemType)
Expand Down
32 changes: 31 additions & 1 deletion Zotero/Models/FieldKeys.swift
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ struct FieldKeys {
return [Annotation.color, Annotation.comment, Annotation.pageLabel, Annotation.position, Annotation.text, Annotation.type, Annotation.sortIndex, Annotation.authorName]
}

static func fields(for type: AnnotationType) -> [KeyBaseKeyPair] {
static func mandatoryApiFields(for type: AnnotationType) -> [KeyBaseKeyPair] {
switch type {
case .highlight:
return [KeyBaseKeyPair(key: Annotation.type, baseKey: nil),
Expand All @@ -96,6 +96,36 @@ struct FieldKeys {
KeyBaseKeyPair(key: Annotation.sortIndex, baseKey: nil)]
}
}

static func allFields(for type: AnnotationType) -> [KeyBaseKeyPair] {
switch type {
case .highlight:
return [KeyBaseKeyPair(key: Annotation.type, baseKey: nil),
KeyBaseKeyPair(key: Annotation.comment, baseKey: nil),
KeyBaseKeyPair(key: Annotation.color, baseKey: nil),
KeyBaseKeyPair(key: Annotation.pageLabel, baseKey: nil),
KeyBaseKeyPair(key: Annotation.sortIndex, baseKey: nil),
KeyBaseKeyPair(key: Annotation.text, baseKey: nil),
KeyBaseKeyPair(key: Annotation.Position.pageIndex, baseKey: Annotation.position)]

case .ink:
return [KeyBaseKeyPair(key: Annotation.type, baseKey: nil),
KeyBaseKeyPair(key: Annotation.comment, baseKey: nil),
KeyBaseKeyPair(key: Annotation.color, baseKey: nil),
KeyBaseKeyPair(key: Annotation.pageLabel, baseKey: nil),
KeyBaseKeyPair(key: Annotation.sortIndex, baseKey: nil),
KeyBaseKeyPair(key: Annotation.Position.pageIndex, baseKey: Annotation.position),
KeyBaseKeyPair(key: Annotation.Position.lineWidth, baseKey: Annotation.position)]

case .note, .image:
return [KeyBaseKeyPair(key: Annotation.type, baseKey: nil),
KeyBaseKeyPair(key: Annotation.comment, baseKey: nil),
KeyBaseKeyPair(key: Annotation.color, baseKey: nil),
KeyBaseKeyPair(key: Annotation.pageLabel, baseKey: nil),
KeyBaseKeyPair(key: Annotation.sortIndex, baseKey: nil),
KeyBaseKeyPair(key: Annotation.Position.pageIndex, baseKey: Annotation.position)]
}
}
}

static func clean(doi: String) -> String {
Expand Down
4 changes: 3 additions & 1 deletion Zotero/Scenes/Detail/PDF/Models/PDFReaderAction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ enum PDFReaderAction {
case userInterfaceStyleChanged(UIUserInterfaceStyle)
case updateAnnotationPreviews
case setToolOptions(color: String?, size: CGFloat?, tool: PSPDFKit.Annotation.Tool)
case create(annotation: AnnotationType, pageIndex: PageIndex, origin: CGPoint)
case createNote(pageIndex: PageIndex, origin: CGPoint)
case createImage(pageIndex: PageIndex, origin: CGPoint)
case createHighlight(pageIndex: PageIndex, rects: [CGRect])
case parseAndCacheComment(key: String, comment: String)
case setComment(key: String, comment: NSAttributedString)
case setCommentActive(Bool)
Expand Down
106 changes: 74 additions & 32 deletions Zotero/Scenes/Detail/PDF/ViewModels/PDFReaderActionHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -178,8 +178,14 @@ final class PDFReaderActionHandler: ViewModelActionHandler, BackgroundDbProcessi
case .setToolOptions(let hex, let size, let tool):
self.setToolOptions(hex: hex, size: size, tool: tool, in: viewModel)

case .create(let annotation, let pageIndex, let origin):
self.add(annotationType: annotation, pageIndex: pageIndex, origin: origin, in: viewModel)
case .createImage(let pageIndex, let origin):
self.addImage(onPage: pageIndex, origin: origin, in: viewModel)

case .createNote(let pageIndex, let origin):
self.addNote(onPage: pageIndex, origin: origin, in: viewModel)

case .createHighlight(let pageIndex, let rects):
self.addHighlight(onPage: pageIndex, rects: rects, in: viewModel)

case .setVisiblePage(let page):
self.set(page: page, in: viewModel)
Expand Down Expand Up @@ -235,7 +241,7 @@ final class PDFReaderActionHandler: ViewModelActionHandler, BackgroundDbProcessi
let (color, alpha, blendMode) = AnnotationColorGenerator.color(from: UIColor(hex: baseColor), isHighlight: (annotation is PSPDFKit.HighlightAnnotation), userInterfaceStyle: interfaceStyle)
annotation.color = color
annotation.alpha = alpha
if let blendMode = blendMode {
if let blendMode {
annotation.blendMode = blendMode
}
}
Expand Down Expand Up @@ -1033,41 +1039,61 @@ final class PDFReaderActionHandler: ViewModelActionHandler, BackgroundDbProcessi
return .highlight

case .image:
return .image
return .square

case .ink:
return .ink
}
}

private func add(annotationType: AnnotationType, pageIndex: PageIndex, origin: CGPoint, in viewModel: ViewModel<PDFReaderActionHandler>) {
guard let activeColor = viewModel.state.toolColors[self.tool(from: annotationType)] else { return }
private func addImage(onPage pageIndex: PageIndex, origin: CGPoint, in viewModel: ViewModel<PDFReaderActionHandler>) {
guard let activeColor = viewModel.state.toolColors[self.tool(from: .image)] else { return }
let color = AnnotationColorGenerator.color(from: activeColor, isHighlight: false, userInterfaceStyle: viewModel.state.interfaceStyle).color
let pdfAnnotation: PSPDFKit.Annotation
let rect = CGRect(origin: origin, size: CGSize(width: 100, height: 100))

switch annotationType {
case .highlight, .ink: return
let square = SquareAnnotation()
square.pageIndex = pageIndex
square.boundingBox = rect
square.borderColor = color
square.lineWidth = AnnotationsConfig.imageAnnotationLineWidth

case .image:
let rect = CGRect(origin: origin, size: CGSize(width: 50, height: 50))
let square = SquareAnnotation()
square.pageIndex = pageIndex
square.boundingBox = rect
square.borderColor = color
pdfAnnotation = square
viewModel.state.document.undoController.recordCommand(named: nil, adding: [square]) {
viewModel.state.document.add(annotations: [square], options: nil)
}
}

case .note:
let rect = CGRect(origin: origin, size: AnnotationsConfig.noteAnnotationSize)
let note = NoteAnnotation(contents: "")
note.pageIndex = pageIndex
note.boundingBox = rect
note.borderStyle = .dashed
note.color = color
pdfAnnotation = note
private func addNote(onPage pageIndex: PageIndex, origin: CGPoint, in viewModel: ViewModel<PDFReaderActionHandler>) {
guard let activeColor = viewModel.state.toolColors[self.tool(from: .note)] else { return }
let color = AnnotationColorGenerator.color(from: activeColor, isHighlight: false, userInterfaceStyle: viewModel.state.interfaceStyle).color
let rect = CGRect(origin: origin, size: AnnotationsConfig.noteAnnotationSize)

let note = NoteAnnotation(contents: "")
note.pageIndex = pageIndex
note.boundingBox = rect
note.borderStyle = .dashed
note.color = color

viewModel.state.document.undoController.recordCommand(named: nil, adding: [note]) {
viewModel.state.document.add(annotations: [note], options: nil)
}
}

private func addHighlight(onPage pageIndex: PageIndex, rects: [CGRect], in viewModel: ViewModel<PDFReaderActionHandler>) {
guard let activeColor = viewModel.state.toolColors[self.tool(from: .highlight)] else { return }
let (color, alpha, blendMode) = AnnotationColorGenerator.color(from: activeColor, isHighlight: true, userInterfaceStyle: viewModel.state.interfaceStyle)

let highlight = HighlightAnnotation()
highlight.rects = rects
highlight.boundingBox = AnnotationBoundingBoxCalculator.boundingBox(from: rects)
highlight.alpha = alpha
highlight.color = color
if let blendMode {
highlight.blendMode = blendMode
}
highlight.pageIndex = pageIndex

viewModel.state.document.undoController.recordCommand(named: nil, adding: [pdfAnnotation]) {
viewModel.state.document.add(annotations: [pdfAnnotation], options: nil)
viewModel.state.document.undoController.recordCommand(named: nil, adding: [highlight]) {
viewModel.state.document.add(annotations: [highlight], options: nil)
}
}

Expand Down Expand Up @@ -1211,7 +1237,7 @@ final class PDFReaderActionHandler: ViewModelActionHandler, BackgroundDbProcessi
let (_color, alpha, blendMode) = AnnotationColorGenerator.color(from: UIColor(hex: color), isHighlight: (annotation.type == .highlight), userInterfaceStyle: interfaceStyle)
pdfAnnotation.color = _color
pdfAnnotation.alpha = alpha
if let blendMode = blendMode {
if let blendMode {
pdfAnnotation.blendMode = blendMode
}
}
Expand All @@ -1235,8 +1261,14 @@ final class PDFReaderActionHandler: ViewModelActionHandler, BackgroundDbProcessi

guard !finalAnnotations.isEmpty else { return }

let request = CreateAnnotationsDbRequest(attachmentKey: viewModel.state.key, libraryId: viewModel.state.library.identifier, annotations: finalAnnotations, userId: viewModel.state.userId,
schemaController: self.schemaController, boundingBoxConverter: boundingBoxConverter)
let request = CreateAnnotationsDbRequest(
attachmentKey: viewModel.state.key,
libraryId: viewModel.state.library.identifier,
annotations: finalAnnotations,
userId: viewModel.state.userId,
schemaController: self.schemaController,
boundingBoxConverter: boundingBoxConverter
)
self.perform(request: request) { [weak self, weak viewModel] error in
guard let error = error, let self = self, let viewModel = viewModel else { return }

Expand Down Expand Up @@ -1349,8 +1381,18 @@ final class PDFReaderActionHandler: ViewModelActionHandler, BackgroundDbProcessi
toAdd.append(contentsOf: splitAnnotations)
}

documentAnnotations.append(contentsOf: splitAnnotations.compactMap({ AnnotationConverter.annotation(from: $0, color: activeColorString, library: state.library, username: state.username,
displayName: state.displayName, boundingBoxConverter: self.delegate) }))
documentAnnotations.append(contentsOf:
splitAnnotations.compactMap({
AnnotationConverter.annotation(
from: $0,
color: activeColorString,
library: state.library,
username: state.username,
displayName: state.displayName,
boundingBoxConverter: self.delegate
)
})
)

for pdfAnnotation in splitAnnotations {
self.annotationPreviewController.store(for: pdfAnnotation, parentKey: state.key, libraryId: state.library.identifier, isDark: (state.interfaceStyle == .dark))
Expand Down Expand Up @@ -1891,7 +1933,7 @@ final class PDFReaderActionHandler: ViewModelActionHandler, BackgroundDbProcessi
let (color, alpha, blendMode) = AnnotationColorGenerator.color(from: UIColor(hex: hexColor), isHighlight: (annotation.type == .highlight), userInterfaceStyle: interfaceStyle)
pdfAnnotation.color = color
pdfAnnotation.alpha = alpha
if let blendMode = blendMode {
if let blendMode {
pdfAnnotation.blendMode = blendMode
}

Expand Down
Loading

0 comments on commit 75274ff

Please sign in to comment.