refactor: split reader architecture and chrome handling
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
import UIKit
|
||||
|
||||
// MARK: - RDReaderView 数据源与代理
|
||||
|
||||
extension RDEPUBReaderController: RDReaderDataSource, RDReaderDelegate {
|
||||
public func pageCountOfReaderView(readerView: RDReaderView) -> Int {
|
||||
textBook?.pages.count ?? activePages.count
|
||||
}
|
||||
|
||||
public func pageContentView(readerView: RDReaderView, pageNum: Int, containerView: UIView?) -> UIView {
|
||||
if let textBook, let page = textBook.page(at: pageNum + 1) {
|
||||
let contentView = (containerView as? RDEPUBTextContentView) ?? RDEPUBTextContentView()
|
||||
contentView.delegate = self
|
||||
contentView.configure(
|
||||
page: page,
|
||||
pageNumber: pageNum + 1,
|
||||
totalPages: textBook.pages.count,
|
||||
configuration: configuration,
|
||||
highlights: textHighlights(for: page),
|
||||
searchState: searchState
|
||||
)
|
||||
return contentView
|
||||
}
|
||||
|
||||
guard let publication,
|
||||
let request = request(for: pageNum) else {
|
||||
return containerView ?? UIView()
|
||||
}
|
||||
|
||||
let contentView = (containerView as? RDEPUBWebContentView) ?? RDEPUBWebContentView()
|
||||
contentView.delegate = self
|
||||
contentView.configure(
|
||||
publication: publication,
|
||||
request: request,
|
||||
pageNumber: pageNum + 1,
|
||||
totalPages: activePages.count,
|
||||
theme: configuration.theme
|
||||
)
|
||||
return contentView
|
||||
}
|
||||
|
||||
public func pageIdentifier(readerView: RDReaderView, pageNum: Int) -> String? {
|
||||
textBook == nil
|
||||
? NSStringFromClass(RDEPUBWebContentView.self)
|
||||
: NSStringFromClass(RDEPUBTextContentView.self)
|
||||
}
|
||||
|
||||
private func textHighlights(for page: RDEPUBTextPage) -> [RDEPUBHighlight] {
|
||||
if let textBook,
|
||||
let chapterData = textBook.chapterData(for: page.href) {
|
||||
return chapterData.highlights(on: page, from: activeHighlights)
|
||||
}
|
||||
|
||||
guard let publication else {
|
||||
return activeHighlights.filter { $0.location.href == page.href }
|
||||
}
|
||||
let pageHref = publication.resourceResolver.normalizedHref(page.href) ?? page.href
|
||||
return activeHighlights.filter {
|
||||
(publication.resourceResolver.normalizedHref($0.location.href) ?? $0.location.href) == pageHref
|
||||
}
|
||||
}
|
||||
|
||||
func textChapterData(forNormalizedHref href: String) -> RDEPUBChapterData? {
|
||||
readerContext.textChapterData(forNormalizedHref: href)
|
||||
}
|
||||
|
||||
public func topToolView(readerView: RDReaderView) -> UIView? {
|
||||
topToolView
|
||||
}
|
||||
|
||||
public func bottomToolView(readerView: RDReaderView) -> UIView? {
|
||||
bottomToolView
|
||||
}
|
||||
|
||||
public func pageNum(readerView: RDReaderView, pageNum: Int) {
|
||||
updateCurrentSelection(nil)
|
||||
reconcileTextPaginationSizeIfNeeded(for: pageNum)
|
||||
|
||||
let totalPages = pageCountOfReaderView(readerView: readerView)
|
||||
if totalPages > 0, pageNum == totalPages - 1 {
|
||||
delegate?.epubReaderDidReachEnd(self)
|
||||
}
|
||||
|
||||
if textBook != nil,
|
||||
let location = resolvedTextLocation(forPageNumber: pageNum + 1) {
|
||||
persist(location: location)
|
||||
synchronizeTextReadingState(pageNumber: pageNum + 1, location: location)
|
||||
return
|
||||
}
|
||||
|
||||
if let location = fallbackLocation(for: pageNum) {
|
||||
persist(location: location)
|
||||
}
|
||||
if readingSession?.navigatorState == .jumping || readingSession?.navigatorState == .moving {
|
||||
readingSession?.transition(to: .idle)
|
||||
}
|
||||
}
|
||||
|
||||
public func readerViewOrientationWillChange(readerView: RDReaderView, isLandscape: Bool) {
|
||||
_ = isLandscape
|
||||
runtime.viewportMonitor.capturePendingPresentationRestoreLocation()
|
||||
}
|
||||
|
||||
private func reconcileTextPaginationSizeIfNeeded(for pageNum: Int) {
|
||||
guard textBook != nil,
|
||||
!isRepaginating,
|
||||
!isReconcilingTextPaginationSize,
|
||||
pageNum >= 0,
|
||||
let lastTextPaginationPageSize else {
|
||||
return
|
||||
}
|
||||
|
||||
let resolvedSize = readerView.resolvedSinglePageSize(pageNum: pageNum)
|
||||
guard resolvedSize.width > 0,
|
||||
resolvedSize.height > 0 else {
|
||||
return
|
||||
}
|
||||
|
||||
let sizeChanged = abs(resolvedSize.width - lastTextPaginationPageSize.width) > 0.5
|
||||
|| abs(resolvedSize.height - lastTextPaginationPageSize.height) > 0.5
|
||||
guard sizeChanged else {
|
||||
return
|
||||
}
|
||||
|
||||
isReconcilingTextPaginationSize = true
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self else { return }
|
||||
self.isReconcilingTextPaginationSize = false
|
||||
guard self.textBook != nil, !self.isRepaginating else { return }
|
||||
self.repaginatePreservingCurrentLocation()
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user