Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,18 @@ class HtmlEpubDocumentViewController: UIViewController {
}

private let viewModel: ViewModel<HtmlEpubReaderActionHandler>
private let pencilInteraction: UIPencilInteraction
private let disposeBag: DisposeBag

private static var toolHistory: [AnnotationTool?] = []
private weak var webView: WKWebView!
private var webViewHandler: WebViewHandler!
weak var parentDelegate: HtmlEpubReaderContainerDelegate?

init(viewModel: ViewModel<HtmlEpubReaderActionHandler>) {
self.viewModel = viewModel
disposeBag = DisposeBag()
pencilInteraction = UIPencilInteraction()
super.init(nibName: nil, bundle: nil)
}

Expand All @@ -43,7 +46,10 @@ class HtmlEpubDocumentViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()

pencilInteraction.delegate = self
view.addInteraction(pencilInteraction)
observeViewModel()
observePenSettingsChange()
setupWebView()
viewModel.process(action: .initialiseReader)

Expand All @@ -55,6 +61,17 @@ class HtmlEpubDocumentViewController: UIViewController {
})
.disposed(by: disposeBag)
}

func observePenSettingsChange() {
NotificationCenter.default.rx
.notification(UIApplication.didBecomeActiveNotification)
.observe(on: MainScheduler.instance)
.subscribe(onNext: { [weak self] _ in
guard let self else { return }
webViewHandler.call(javascript: "window._view.setPenExclusive(\(UIPencilInteraction.prefersPencilOnlyDrawing));").subscribe().disposed(by: disposeBag)
})
.disposed(by: disposeBag)
}

func setupWebView() {
let highlightAction = UIAction(title: L10n.Pdf.highlight) { [weak self] _ in
Expand Down Expand Up @@ -91,6 +108,25 @@ class HtmlEpubDocumentViewController: UIViewController {

// MARK: - Actions

func toggle(tool: AnnotationTool, tappedWithStylus: Bool) {
viewModel.process(action: .toggleTool(tool))
if Self.toolHistory.last != viewModel.state.activeTool {
Self.toolHistory.append(viewModel.state.activeTool)
if Self.toolHistory.count > 2 {
Self.toolHistory.remove(at: 0)
}
}
if viewModel.state.activeTool == nil {
set(penActive: false)
} else if tappedWithStylus {
set(penActive: true)
}

func set(penActive: Bool) {
webViewHandler.call(javascript: "window._view.setPenActive(\(penActive));").subscribe().disposed(by: disposeBag)
}
}

func show(location: [String: Any]) {
webViewHandler.call(javascript: "navigate({ location: \(WebViewEncoder.encodeAsJSONForJavascript(location)) });").subscribe().disposed(by: disposeBag)
}
Expand Down Expand Up @@ -178,7 +214,11 @@ class HtmlEpubDocumentViewController: UIViewController {
func load(documentData data: HtmlEpubReaderState.DocumentData) {
DDLogInfo("HtmlEpubDocumentViewController: try creating view for \(data.type); page = \(String(describing: data.page))")
DDLogInfo("URL: \(data.url.absoluteString)")
var javascript = "createView({ type: '\(data.type)', url: '\(data.url.absoluteString.replacingOccurrences(of: "'", with: #"\'"#))', annotations: \(data.annotationsJson)"
var javascript = "createView({ type: '\(data.type)', " +
"url: '\(data.url.absoluteString.replacingOccurrences(of: "'", with: #"\'"#))', " +
"penConnected: false, " +
"penExclusive: \(UIPencilInteraction.prefersPencilOnlyDrawing), " +
"annotations: \(data.annotationsJson)"
if let key = data.selectedAnnotationKey {
javascript += ", location: {annotationID: '\(key)'}"
} else if let page = data.page {
Expand Down Expand Up @@ -339,3 +379,57 @@ extension HtmlEpubDocumentViewController: ParentWithSidebarDocumentController {
viewModel.process(action: .toggleTool(tool))
}
}

extension HtmlEpubDocumentViewController: UIPencilInteractionDelegate {
private func process(action: UIPencilPreferredAction) {
guard parentDelegate?.isToolbarVisible == true else { return }
switch action {
case .switchEraser:
guard viewModel.state.activeTool != nil else { return }
if viewModel.state.activeTool != .eraser {
toggle(tool: .eraser, tappedWithStylus: true)
} else {
let previous = (HtmlEpubDocumentViewController.toolHistory.last(where: { $0 != .eraser }) ?? nil) ?? .highlight
toggle(tool: previous, tappedWithStylus: true)
}

case .switchPrevious:
let previous: AnnotationTool
if let tool = viewModel.state.activeTool {
// Find the most recent different tool – if it's the "nil tool", default to `tool` to unset current tool
previous = (HtmlEpubDocumentViewController.toolHistory.last(where: { $0 != tool }) ?? nil) ?? tool
} else {
// Since we can't switch from nil to nil, find the most recent non-nil tool, default to .highlight
previous = (HtmlEpubDocumentViewController.toolHistory.last(where: { $0 != nil }) ?? nil) ?? .highlight
}
toggle(tool: previous, tappedWithStylus: true)

case .showColorPalette, .showInkAttributes, .showContextualPalette:
parentDelegate?.showToolOptions()

case .runSystemShortcut, .ignore:
break

@unknown default:
break
}
}

func pencilInteractionDidTap(_ interaction: UIPencilInteraction) {
process(action: UIPencilInteraction.preferredTapAction)
}

@available(iOS 17.5, *)
func pencilInteraction(_ interaction: UIPencilInteraction, didReceiveSqueeze squeeze: UIPencilInteraction.Squeeze) {
switch squeeze.phase {
case .ended:
process(action: UIPencilInteraction.preferredSqueezeAction)

case .began, .changed, .cancelled:
break

@unknown default:
break
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@ protocol HtmlEpubReaderContainerDelegate: AnyObject {
var statusBarHeight: CGFloat { get }
var navigationBarHeight: CGFloat { get }
var isSidebarVisible: Bool { get }
var isToolbarVisible: Bool { get }

func show(url: URL)
func toggleInterfaceVisibility()
func showToolOptions()
}

class HtmlEpubReaderViewController: UIViewController, ReaderViewController, ParentWithSidebarController {
Expand Down Expand Up @@ -60,6 +62,7 @@ class HtmlEpubReaderViewController: UIViewController, ReaderViewController, Pare
}
}
var isSidebarVisible: Bool { return self.sidebarControllerLeft?.constant == 0 }
var isToolbarVisible: Bool { return toolbarState.visible }
var isDocumentLocked: Bool { return false }
private(set) var activeAnnotationTool: AnnotationTool?
lazy var toolbarButton: UIBarButtonItem = {
Expand Down Expand Up @@ -501,7 +504,7 @@ extension HtmlEpubReaderViewController: AnnotationToolbarDelegate {
}

func toggle(tool: AnnotationTool, options: AnnotationToolOptions) {
viewModel.process(action: .toggleTool(tool))
documentController?.toggle(tool: tool, tappedWithStylus: options == .stylus)
}

func showToolOptions(sourceItem: UIPopoverPresentationControllerSourceItem) {
Expand Down Expand Up @@ -564,6 +567,16 @@ extension HtmlEpubReaderViewController: HtmlEpubReaderContainerDelegate {
toggleSidebar(animated: true)
}
}

func showToolOptions() {
if let annotationToolbarController, !annotationToolbarController.view.isHidden, !annotationToolbarController.colorPickerButton.isHidden {
showToolOptions(sourceItem: annotationToolbarController.colorPickerButton)
return
}

guard let item = navigationItem.rightBarButtonItems?.last else { return }
showToolOptions(sourceItem: item)
}
}

extension HtmlEpubReaderViewController: ReaderAnnotationsDelegate {
Expand Down
Loading