ReadViewSDK/Sources/RDReaderView/EPUBUI/ReaderController/RDEPUBReaderRuntime.swift

282 lines
8.7 KiB
Swift

import UIKit
final class RDEPUBReaderRuntime {
private unowned let context: RDEPUBReaderContext
lazy var loadCoordinator = RDEPUBReaderLoadCoordinator(context: context)
lazy var paginationCoordinator = RDEPUBReaderPaginationCoordinator(context: context)
lazy var locationCoordinator = RDEPUBReaderLocationCoordinator(context: context)
lazy var searchCoordinator = RDEPUBReaderSearchCoordinator(context: context)
lazy var chromeCoordinator = RDEPUBReaderChromeCoordinator(context: context)
lazy var annotationCoordinator = RDEPUBReaderAnnotationCoordinator(context: context)
lazy var viewportMonitor = RDEPUBReaderViewportMonitor(context: context)
init(context: RDEPUBReaderContext) {
self.context = context
}
func makeTopToolView() -> RDEPUBReaderTopToolView {
chromeCoordinator.makeTopToolView()
}
func makeBottomToolView() -> RDEPUBReaderBottomToolView {
chromeCoordinator.makeBottomToolView()
}
func startInitialLoadIfNeeded() {
loadCoordinator.startInitialLoadIfNeeded()
}
func reloadBook() {
guard let readerView = context.readerView else { return }
context.didStartInitialLoad = false
context.parser = nil
context.publication = nil
context.clearActiveSnapshot()
context.readingSession = nil
context.textBook = nil
context.activeBookmarks = []
context.activeHighlights = []
context.searchState = nil
viewportMonitor.resetForReload()
annotationCoordinator.updateCurrentSelection(nil)
readerView.reloadData()
startInitialLoadIfNeeded()
}
func go(to location: RDEPUBLocation, animated: Bool = false) -> Bool {
locationCoordinator.restoreReadingLocation(location, animated: animated)
}
@discardableResult
func go(toPageNumber pageNumber: Int, animated: Bool = false) -> Bool {
guard let controller = context.controller,
let readerView = context.readerView,
pageNumber > 0 else {
return false
}
if context.textBook != nil {
guard let location = controller.resolvedTextLocation(forPageNumber: pageNumber) else {
return false
}
return locationCoordinator.restoreReadingLocation(location, animated: animated)
}
guard context.activePages.indices.contains(pageNumber - 1) else {
return false
}
readerView.transitionToPage(pageNum: pageNumber - 1, animated: animated)
if let location = locationCoordinator.currentVisibleLocation() {
context.persist(location: location)
}
return true
}
func clearSelection() {
annotationCoordinator.updateCurrentSelection(nil)
}
func bookmark(withID id: String) -> RDEPUBBookmark? {
annotationCoordinator.bookmark(withID: id)
}
func highlight(withID id: String) -> RDEPUBHighlight? {
annotationCoordinator.highlight(withID: id)
}
@discardableResult
func addHighlight(
from selection: RDEPUBSelection? = nil,
color: String = "#F8E16C",
note: String? = nil
) -> RDEPUBHighlight? {
annotationCoordinator.addHighlight(from: selection, color: color, note: note)
}
@discardableResult
func addAnnotation(
from selection: RDEPUBSelection? = nil,
style: RDEPUBHighlightStyle,
color: String = "#F8E16C",
note: String? = nil
) -> RDEPUBHighlight? {
annotationCoordinator.addAnnotation(from: selection, style: style, color: color, note: note)
}
@discardableResult
func upsertHighlight(_ highlight: RDEPUBHighlight) -> RDEPUBHighlight? {
annotationCoordinator.upsertHighlight(highlight)
}
@discardableResult
func removeHighlight(id: String) -> RDEPUBHighlight? {
annotationCoordinator.removeHighlight(id: id)
}
@discardableResult
func updateHighlightNote(id: String, note: String?) -> RDEPUBHighlight? {
annotationCoordinator.updateHighlightNote(id: id, note: note)
}
@discardableResult
func go(toHighlightID id: String, animated: Bool = true) -> Bool {
annotationCoordinator.go(toHighlightID: id, animated: animated)
}
func removeAllHighlights() {
annotationCoordinator.removeAllHighlights()
}
@discardableResult
func addBookmark(note: String? = nil) -> RDEPUBBookmark? {
annotationCoordinator.addBookmark(note: note)
}
@discardableResult
func toggleBookmark(note: String? = nil) -> RDEPUBBookmark? {
annotationCoordinator.toggleBookmark(note: note)
}
@discardableResult
func removeBookmark(id: String) -> RDEPUBBookmark? {
annotationCoordinator.removeBookmark(id: id)
}
@discardableResult
func go(toBookmarkID id: String, animated: Bool = true) -> Bool {
annotationCoordinator.go(toBookmarkID: id, animated: animated)
}
func updateBookmarkChrome() {
annotationCoordinator.updateBookmarkChrome()
}
func presentBookmarksManager() {
annotationCoordinator.presentBookmarksManager()
}
func presentHighlightsManager() {
annotationCoordinator.presentHighlightsManager()
}
func presentAnnotationCreation() {
annotationCoordinator.presentAnnotationCreation()
}
func handleSelectionMenuAction(_ action: RDEPUBAnnotationMenuAction, selection: RDEPUBSelection?) {
annotationCoordinator.handleSelectionMenuAction(action, selection: selection)
}
func search(keyword: String) {
searchCoordinator.search(keyword: keyword)
}
@discardableResult
func searchNext() -> Bool {
searchCoordinator.searchNext()
}
@discardableResult
func searchPrevious() -> Bool {
searchCoordinator.searchPrevious()
}
func clearSearch() {
searchCoordinator.clearSearch()
}
func searchPresentation(for page: EPUBPage) -> RDEPUBSearchPresentation? {
searchCoordinator.searchPresentation(for: page)
}
func updateReaderChrome() {
chromeCoordinator.updateReaderChrome()
}
func presentSettings() {
chromeCoordinator.presentSettings()
}
func presentTableOfContents() {
chromeCoordinator.presentTableOfContents()
}
func handleBackAction() {
chromeCoordinator.handleBackAction()
}
func loadPublication() {
loadCoordinator.loadPublication()
}
func applyParsedPublication(
parser: RDEPUBParser,
publication: RDEPUBPublication,
bookIdentifier: String,
restoreLocation: RDEPUBLocation?,
bookmarks: [RDEPUBBookmark],
highlights: [RDEPUBHighlight]
) {
loadCoordinator.applyParsedPublication(
parser: parser,
publication: publication,
bookIdentifier: bookIdentifier,
restoreLocation: restoreLocation,
bookmarks: bookmarks,
highlights: highlights
)
}
func paginatePublication(restoreLocation: RDEPUBLocation?) {
paginationCoordinator.paginatePublication(restoreLocation: restoreLocation)
}
func applyTextBook(_ textBook: RDEPUBTextBook, restoreLocation: RDEPUBLocation?) {
paginationCoordinator.applyTextBook(textBook, restoreLocation: restoreLocation)
}
func applyPaginationSnapshot(
_ snapshot: (pages: [EPUBPage], chapters: [EPUBChapterInfo]),
restoreLocation: RDEPUBLocation?
) {
paginationCoordinator.applyPaginationSnapshot(snapshot, restoreLocation: restoreLocation)
}
func finishPagination(restoreLocation: RDEPUBLocation?) {
paginationCoordinator.finishPagination(restoreLocation: restoreLocation)
}
func repaginatePreservingCurrentLocation() {
paginationCoordinator.repaginatePreservingCurrentLocation()
}
func refreshVisibleContentPreservingLocation() {
paginationCoordinator.refreshVisibleContentPreservingLocation()
}
func rebuildExternalTextBook() {
paginationCoordinator.rebuildExternalTextBook()
}
@discardableResult
func restoreReadingLocation(_ location: RDEPUBLocation, animated: Bool = false) -> Bool {
locationCoordinator.restoreReadingLocation(location, animated: animated)
}
func currentVisibleLocation() -> RDEPUBLocation? {
locationCoordinator.currentVisibleLocation()
}
func currentViewportSignature() -> RDEPUBViewportSignature? {
viewportMonitor.currentViewportSignature()
}
func handleViewportChangeIfNeeded(
reason: RDEPUBViewportChangeReason,
viewportSignature: RDEPUBViewportSignature? = nil
) {
viewportMonitor.handleViewportChangeIfNeeded(reason: reason, viewportSignature: viewportSignature)
}
}