更新阅读器功能与示例

This commit is contained in:
shen
2026-07-27 21:43:13 +08:00
parent 68d9363f0a
commit 9392027106
78 changed files with 8780 additions and 2084 deletions
@@ -164,14 +164,14 @@ extension RDEPUBReaderController: RDEpubReaderDataSource, RDEpubReaderPageProvid
private func textHighlights(for page: RDEPUBTextPage) -> [RDEPUBHighlight] {
if let textBook,
let chapterData = textBook.chapterData(for: page.href) {
return chapterData.highlights(on: page, from: activeHighlights)
return chapterData.highlights(on: page, from: activeHighlights + transientHighlights)
}
guard let publication else {
return activeHighlights.filter { $0.location.href == page.href }
return (activeHighlights + transientHighlights).filter { $0.location.href == page.href }
}
let pageHref = publication.resourceResolver.normalizedHref(page.href) ?? page.href
return activeHighlights.filter {
return (activeHighlights + transientHighlights).filter {
(publication.resourceResolver.normalizedHref($0.location.href) ?? $0.location.href) == pageHref
}
}
@@ -21,6 +21,18 @@ extension RDEPUBReaderController {
runtime.clearSelection()
}
/// Displays temporary decorations without mutating annotation persistence.
public func setTransientHighlights(_ highlights: [RDEPUBHighlight]) {
transientHighlights = highlights
refreshVisibleContentPreservingLocation()
}
public func clearTransientHighlights() {
guard !transientHighlights.isEmpty else { return }
transientHighlights.removeAll()
refreshVisibleContentPreservingLocation()
}
public func bookmark(withID id: String) -> RDEPUBBookmark? {
runtime.bookmark(withID: id)
}
@@ -69,7 +69,7 @@ extension RDEPUBReaderController {
guard let publication else { return [] }
if let spread = page.fixedSpread {
let hrefs = Set(spread.resources.compactMap { publication.resourceResolver.normalizedHref($0.href) })
return activeHighlights.filter { highlight in
return (activeHighlights + transientHighlights).filter { highlight in
guard let normalizedHref = publication.resourceResolver.normalizedHref(highlight.location.href) else {
return false
}
@@ -80,7 +80,7 @@ extension RDEPUBReaderController {
guard publication.spine.indices.contains(page.spineIndex) else { return [] }
let href = publication.spine[page.spineIndex].href
let normalizedHref = publication.resourceResolver.normalizedHref(href)
return activeHighlights.filter { highlight in
return (activeHighlights + transientHighlights).filter { highlight in
publication.resourceResolver.normalizedHref(highlight.location.href) == normalizedHref
}
}
@@ -140,6 +140,11 @@ public final class RDEPUBReaderController: UIViewController {
set { readerContext.activeHighlights = newValue }
}
var transientHighlights: [RDEPUBHighlight] {
get { readerContext.transientHighlights }
set { readerContext.transientHighlights = newValue }
}
lazy var topToolView = runtime.makeTopToolView()
lazy var bottomToolView = runtime.makeBottomToolView()
@@ -72,6 +72,11 @@ final class RDEPUBReaderContext {
set { state.activeHighlights = newValue }
}
var transientHighlights: [RDEPUBHighlight] {
get { state.transientHighlights }
set { state.transientHighlights = newValue }
}
var currentBookIdentifier: String? {
get { state.currentBookIdentifier }
set { state.currentBookIdentifier = newValue }
@@ -20,6 +20,9 @@ final class RDEPUBReaderState {
var activeHighlights: [RDEPUBHighlight] = []
// Session-only decorations (for search/AI focus) are never persisted.
var transientHighlights: [RDEPUBHighlight] = []
var currentBookIdentifier: String?
var paginationToken = UUID()