feat: improve epub reader controls and annotations

This commit is contained in:
shen
2026-07-12 12:23:10 +08:00
parent 063a493b18
commit 8ccb7157b2
36 changed files with 2959 additions and 2160 deletions
@@ -74,9 +74,9 @@ extension RDEPUBAnnotationWebView: UIEditMenuInteractionDelegate {
menuFor configuration: UIEditMenuConfiguration
) -> UIMenu {
UIMenu(children: [
UICommand(title: "拷贝", action: #selector(rd_copy(_:))),
UICommand(title: "高亮", action: #selector(rd_highlight(_:))),
UICommand(title: "", action: #selector(rd_annotate(_:)))
UICommand(title: "复制", action: #selector(rd_copy(_:))),
UICommand(title: "划线", action: #selector(rd_highlight(_:))),
UICommand(title: "", action: #selector(rd_annotate(_:)))
])
}
@@ -138,6 +138,24 @@ public final class RDEPUBWebView: UIView {
var isReaderPageVisible = true
var hasReaderPageBeenVisible = false
var needsReaderPagePlaybackRestart = false
var appliedNativeMediaPlaybackSuspended = false
var isNativeMediaPlaybackOperationInFlight = false
var nativeMediaPlaybackOperationGeneration: UInt = 0
var nativeMediaPlaybackRequests: [(suspended: Bool, completion: () -> Void)] = []
var isWaitingForReaderPageMediaNavigation = false
var pendingReaderPageMediaNavigation: WKNavigation?
var isReaderPageMediaActivationBlocked = false
var pendingProgressionRequest = false
var fixedLayoutReadyWorkItem: DispatchWorkItem?
@@ -189,6 +207,11 @@ public final class RDEPUBWebView: UIView {
fixedSpread = nil
isFixedLayout = false
isReaderPageVisible = true
hasReaderPageBeenVisible = false
needsReaderPagePlaybackRestart = false
isWaitingForReaderPageMediaNavigation = false
pendingReaderPageMediaNavigation = nil
isReaderPageMediaActivationBlocked = false
pendingProgressionRequest = false
didRenderCurrentRequest = false
teardownWebView()
@@ -207,6 +230,15 @@ public final class RDEPUBWebView: UIView {
let publicationKey = publication.parser.opfURL?.path ?? publication.parser.extractionRootURL?.path ?? ""
let loadSignature = pageLoadSignature(publicationKey: publicationKey, request: request)
if request.isFixedLayout {
// A fixed-layout load replaces the whole Hype document. Keep WebKit
// suspended until navigation finishes so the outgoing page cannot
// overlap the new page's zero-second narration.
hasReaderPageBeenVisible = false
needsReaderPagePlaybackRestart = false
isWaitingForReaderPageMediaNavigation = true
setNativeReaderPageMediaPlaybackSuspended(true)
}
RDEPUBWebViewDebug.log(
debugScope,
message: "load request=\(request.isFixedLayout ? "fixed" : "reflowable") signature=\(loadSignature) webView=\(RDEPUBWebViewDebug.webViewID(webView))"