Skip to content

Commit

Permalink
Merge common reader sidebar coordinator delegate functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
mvasilak committed Sep 18, 2024
1 parent 5113ab7 commit d512d61
Show file tree
Hide file tree
Showing 11 changed files with 333 additions and 282 deletions.
4 changes: 4 additions & 0 deletions Zotero.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
614D65822A79C9AC007CF449 /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = 614D65802A79C9AC007CF449 /* Localizable.stringsdict */; };
614D65832A79C9B0007CF449 /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = 614D65802A79C9AC007CF449 /* Localizable.stringsdict */; };
614D65872A8030C9007CF449 /* OrderedCollections in Frameworks */ = {isa = PBXBuildFile; productRef = 614D65862A8030C9007CF449 /* OrderedCollections */; };
615FD8772C8B475A00808C1D /* ReaderCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 615FD8762C8B475A00808C1D /* ReaderCoordinator.swift */; };
61639F852AE03B8500026003 /* InstantPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61639F842AE03B8500026003 /* InstantPresenter.swift */; };
618404262A4456A9005AAF22 /* IdentifierLookupController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 618404252A4456A9005AAF22 /* IdentifierLookupController.swift */; };
618D83E72BAAC88C00E7966B /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 618D83E62BAAC88C00E7966B /* PrivacyInfo.xcprivacy */; };
Expand Down Expand Up @@ -1299,6 +1300,7 @@
613F32782C1086950088EF70 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
614D65812A79C9AC007CF449 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = en; path = en.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
614D65842A7BCC22007CF449 /* ci_post_clone.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = ci_post_clone.sh; sourceTree = "<group>"; };
615FD8762C8B475A00808C1D /* ReaderCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReaderCoordinator.swift; sourceTree = "<group>"; };
61639F842AE03B8500026003 /* InstantPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstantPresenter.swift; sourceTree = "<group>"; };
618404252A4456A9005AAF22 /* IdentifierLookupController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IdentifierLookupController.swift; sourceTree = "<group>"; };
618D83E62BAAC88C00E7966B /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
Expand Down Expand Up @@ -3562,6 +3564,7 @@
isa = PBXGroup;
children = (
B3866A592417C1C7006693C4 /* Coordinator.swift */,
615FD8762C8B475A00808C1D /* ReaderCoordinator.swift */,
B3866A572417C1BC006693C4 /* ViewModel.swift */,
);
path = Architecture;
Expand Down Expand Up @@ -4905,6 +4908,7 @@
B3429B8124BDE73A008359FC /* UIDevice+Extensions.swift in Sources */,
B3229FD128C0A07500DAF3B7 /* EditAnnotationRectsDbRequest.swift in Sources */,
B3DF9AD22747AAD2007933CB /* ApiRequest.swift in Sources */,
615FD8772C8B475A00808C1D /* ReaderCoordinator.swift in Sources */,
B3DCDF0E240912500039ED0D /* SinglePickerActionHandler.swift in Sources */,
B3593F162668E29C00FA4BB2 /* Style.swift in Sources */,
B3593F37241A61C700760E20 /* ItemDetailViewController.swift in Sources */,
Expand Down
198 changes: 0 additions & 198 deletions Zotero/Controllers/Architecture/Coordinator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
//

import UIKit
import CocoaLumberjackSwift

enum SourceView {
case view(UIView, CGRect?)
Expand Down Expand Up @@ -71,200 +70,3 @@ extension Coordinator {
(presenter ?? navigationController)?.present(controller, animated: true, completion: nil)
}
}

protocol ReaderAnnotation {
var key: String { get }
var type: AnnotationType { get }
var pageLabel: String { get }
var lineWidth: CGFloat? { get }
var color: String { get }
var comment: String { get }
var text: String? { get }
var fontSize: CGFloat? { get }
var sortIndex: String { get }
var dateModified: Date { get }

func editability(currentUserId: Int, library: Library) -> AnnotationEditability
}

protocol ReaderError: Error {
var title: String { get }
var message: String { get }
}

protocol ReaderCoordinatorDelegate: AnyObject {
func show(error: ReaderError)
func showToolSettings(tool: AnnotationTool, colorHex: String?, sizeValue: Float?, sender: SourceView, userInterfaceStyle: UIUserInterfaceStyle, valueChanged: @escaping (String?, Float?) -> Void)
}

protocol ReaderSidebarCoordinatorDelegate: AnyObject {
func showTagPicker(libraryId: LibraryIdentifier, selected: Set<String>, userInterfaceStyle: UIUserInterfaceStyle?, picked: @escaping ([Tag]) -> Void)
func showCellOptions(
for annotation: ReaderAnnotation,
userId: Int,
library: Library,
highlightFont: UIFont,
sender: UIButton,
userInterfaceStyle: UIUserInterfaceStyle,
saveAction: @escaping AnnotationEditSaveAction,
deleteAction: @escaping AnnotationEditDeleteAction
)
func showFilterPopup(
from barButton: UIBarButtonItem,
filter: AnnotationsFilter?,
availableColors: [String],
availableTags: [Tag],
userInterfaceStyle: UIUserInterfaceStyle,
completed: @escaping (AnnotationsFilter?) -> Void
)
func showSettings(with settings: ReaderSettings, sender: UIBarButtonItem) -> ViewModel<ReaderSettingsActionHandler>
}

protocol ReaderAnnotationsDelegate: AnyObject {
func parseAndCacheIfNeededAttributedText(for annotation: ReaderAnnotation, with font: UIFont) -> NSAttributedString?
func parseAndCacheIfNeededAttributedComment(for annotation: ReaderAnnotation) -> NSAttributedString?
}

protocol ReaderCoordinator: Coordinator, ReaderCoordinatorDelegate, ReaderSidebarCoordinatorDelegate {
var controllers: Controllers { get }
}

extension ReaderCoordinator {
func show(error: ReaderError) {
let controller = UIAlertController(title: error.title, message: error.message, preferredStyle: .alert)
controller.addAction(UIAlertAction(title: L10n.ok, style: .default))
navigationController?.present(controller, animated: true)
}

func showToolSettings(tool: AnnotationTool, colorHex: String?, sizeValue: Float?, sender: SourceView, userInterfaceStyle: UIUserInterfaceStyle, valueChanged: @escaping (String?, Float?) -> Void) {
DDLogInfo("ReaderCoordinator: show tool settings for \(tool)")
let state = AnnotationToolOptionsState(tool: tool, colorHex: colorHex, size: sizeValue)
let handler = AnnotationToolOptionsActionHandler()
let controller = AnnotationToolOptionsViewController(viewModel: ViewModel(initialState: state, handler: handler), valueChanged: valueChanged)

switch UIDevice.current.userInterfaceIdiom {
case .pad:
controller.overrideUserInterfaceStyle = userInterfaceStyle
controller.modalPresentationStyle = .popover
switch sender {
case .view(let view, _):
controller.popoverPresentationController?.sourceView = view

case .item(let item):
controller.popoverPresentationController?.barButtonItem = item
}
navigationController?.present(controller, animated: true, completion: nil)

default:
let navigationController = UINavigationController(rootViewController: controller)
navigationController.modalPresentationStyle = .formSheet
navigationController.overrideUserInterfaceStyle = userInterfaceStyle
self.navigationController?.present(navigationController, animated: true, completion: nil)
}
}
}

extension ReaderCoordinator {
func showTagPicker(libraryId: LibraryIdentifier, selected: Set<String>, userInterfaceStyle: UIUserInterfaceStyle?, picked: @escaping ([Tag]) -> Void) {
guard let navigationController, let parentCoordinator = parentCoordinator as? DetailCoordinator else { return }
parentCoordinator.showTagPicker(libraryId: libraryId, selected: selected, userInterfaceStyle: userInterfaceStyle, navigationController: navigationController, picked: picked)
}

func showCellOptions(
for annotation: any ReaderAnnotation,
userId: Int,
library: Library,
highlightFont: UIFont,
sender: UIButton,
userInterfaceStyle: UIUserInterfaceStyle,
saveAction: @escaping AnnotationEditSaveAction,
deleteAction: @escaping AnnotationEditDeleteAction
) {
let navigationController = NavigationViewController()
navigationController.overrideUserInterfaceStyle = userInterfaceStyle

let highlightText: NSAttributedString = (self.navigationController?.viewControllers.first as? ReaderAnnotationsDelegate)?
.parseAndCacheIfNeededAttributedText(for: annotation, with: highlightFont) ?? .init(string: "")
let coordinator = AnnotationEditCoordinator(
data: AnnotationEditState.Data(
type: annotation.type,
isEditable: annotation.editability(currentUserId: userId, library: library) == .editable,
color: annotation.color,
lineWidth: annotation.lineWidth ?? 0,
pageLabel: annotation.pageLabel,
highlightText: highlightText,
highlightFont: highlightFont,
fontSize: annotation.fontSize
),
saveAction: saveAction,
deleteAction: deleteAction,
navigationController: navigationController,
controllers: controllers
)
coordinator.parentCoordinator = self
childCoordinators.append(coordinator)
coordinator.start(animated: false)

if UIDevice.current.userInterfaceIdiom == .pad {
navigationController.modalPresentationStyle = .popover
navigationController.popoverPresentationController?.sourceView = sender
navigationController.popoverPresentationController?.permittedArrowDirections = .left
}

self.navigationController?.present(navigationController, animated: true, completion: nil)
}

func showFilterPopup(
from barButton: UIBarButtonItem,
filter: AnnotationsFilter?,
availableColors: [String],
availableTags: [Tag],
userInterfaceStyle: UIUserInterfaceStyle,
completed: @escaping (AnnotationsFilter?) -> Void
) {
DDLogInfo("ReaderCoordinator: show annotations filter popup")

let navigationController = NavigationViewController()
navigationController.overrideUserInterfaceStyle = userInterfaceStyle
let coordinator = AnnotationsFilterPopoverCoordinator(
initialFilter: filter,
availableColors: availableColors,
availableTags: availableTags,
navigationController: navigationController,
controllers: controllers,
completionHandler: completed
)
coordinator.parentCoordinator = self
childCoordinators.append(coordinator)
coordinator.start(animated: false)

if UIDevice.current.userInterfaceIdiom == .pad {
navigationController.modalPresentationStyle = .popover
navigationController.popoverPresentationController?.barButtonItem = barButton
navigationController.popoverPresentationController?.permittedArrowDirections = .down
}

self.navigationController?.present(navigationController, animated: true, completion: nil)
}

func showSettings(with settings: ReaderSettings, sender: UIBarButtonItem) -> ViewModel<ReaderSettingsActionHandler> {
DDLogInfo("ReaderCoordinator: show settings")

let state = ReaderSettingsState(settings: settings)
let viewModel = ViewModel(initialState: state, handler: ReaderSettingsActionHandler())
let baseController = ReaderSettingsViewController(rows: settings.rows, viewModel: viewModel)
let controller: UIViewController
if UIDevice.current.userInterfaceIdiom == .pad {
controller = baseController
} else {
controller = UINavigationController(rootViewController: baseController)
}
controller.modalPresentationStyle = UIDevice.current.userInterfaceIdiom == .pad ? .popover : .formSheet
controller.popoverPresentationController?.barButtonItem = sender
controller.preferredContentSize = settings.preferredContentSize
controller.overrideUserInterfaceStyle = settings.appearance.userInterfaceStyle
navigationController?.present(controller, animated: true, completion: nil)

return viewModel
}
}
Loading

0 comments on commit d512d61

Please sign in to comment.