feat(wxread): align pagination, rendering, and docs
This commit is contained in:
+1303
-1271
File diff suppressed because it is too large
Load Diff
Generated
BIN
Binary file not shown.
+36
@@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Bucket
|
||||
uuid = "B0633BC4-5BBB-46C3-9C4F-C3B9A25989D3"
|
||||
type = "0"
|
||||
version = "2.0">
|
||||
<Breakpoints>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
uuid = "7F1DAB5A-519E-47BC-A62E-B330F41132ED"
|
||||
shouldBeEnabled = "Yes"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "../Sources/RDReaderView/EPUBTextRendering/RDEPUBTextBookCache.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "323"
|
||||
endingLineNumber = "323">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
uuid = "0313507F-BD79-4B9D-B92F-703991289849"
|
||||
shouldBeEnabled = "Yes"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "../Sources/RDReaderView/EPUBTextRendering/RDEPUBTextBookCache.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "351"
|
||||
endingLineNumber = "351">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
</Breakpoints>
|
||||
</Bucket>
|
||||
@@ -8,6 +8,57 @@ final class ViewController: UIViewController {
|
||||
let fileURL: URL
|
||||
}
|
||||
|
||||
private struct LaunchAutomationPlan {
|
||||
let bookTitleQuery: String
|
||||
let displayType: RDReaderView.DisplayType?
|
||||
let pageNumber: Int?
|
||||
let displaySequence: [RDReaderView.DisplayType]
|
||||
let stepDelay: TimeInterval
|
||||
|
||||
nonisolated private static func parseDisplayType(_ rawValue: String) -> RDReaderView.DisplayType? {
|
||||
switch rawValue.lowercased() {
|
||||
case "pagecurl", "curl":
|
||||
return .pageCurl
|
||||
case "horizontalscroll", "horizontal", "scroll":
|
||||
return .horizontalScroll
|
||||
case "verticalscroll", "vertical":
|
||||
return .verticalScroll
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
static func parse(arguments: [String]) -> LaunchAutomationPlan? {
|
||||
func value(after flag: String) -> String? {
|
||||
guard let index = arguments.firstIndex(of: flag), arguments.indices.contains(index + 1) else {
|
||||
return nil
|
||||
}
|
||||
return arguments[index + 1]
|
||||
}
|
||||
|
||||
guard let bookTitleQuery = value(after: "--demo-book-title"),
|
||||
!bookTitleQuery.isEmpty else {
|
||||
return nil
|
||||
}
|
||||
|
||||
let displayType = value(after: "--demo-display-type").flatMap(parseDisplayType)
|
||||
let pageNumber = value(after: "--demo-page").flatMap(Int.init)
|
||||
let displaySequence = value(after: "--demo-display-sequence")
|
||||
.map { raw in
|
||||
raw.split(separator: ",").compactMap { parseDisplayType(String($0)) }
|
||||
} ?? []
|
||||
let stepDelay = value(after: "--demo-step-delay").flatMap(TimeInterval.init) ?? 1.0
|
||||
|
||||
return LaunchAutomationPlan(
|
||||
bookTitleQuery: bookTitleQuery,
|
||||
displayType: displayType,
|
||||
pageNumber: pageNumber,
|
||||
displaySequence: displaySequence,
|
||||
stepDelay: stepDelay
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private enum ValidationCategory: String, CaseIterable {
|
||||
case textNovel = "TXT/小说"
|
||||
case textRich = "复杂图文"
|
||||
@@ -111,6 +162,8 @@ final class ViewController: UIViewController {
|
||||
private var books: [DemoBook] = []
|
||||
private var validationSummary: ResourceValidationSummary?
|
||||
private var validationTask: Task<Void, Never>?
|
||||
private let launchAutomationPlan = LaunchAutomationPlan.parse(arguments: ProcessInfo.processInfo.arguments)
|
||||
private var didRunLaunchAutomation = false
|
||||
|
||||
deinit {
|
||||
validationTask?.cancel()
|
||||
@@ -125,6 +178,11 @@ final class ViewController: UIViewController {
|
||||
loadBooks()
|
||||
}
|
||||
|
||||
override func viewDidAppear(_ animated: Bool) {
|
||||
super.viewDidAppear(animated)
|
||||
runLaunchAutomationIfNeeded()
|
||||
}
|
||||
|
||||
private func setupViews() {
|
||||
tableView.dataSource = self
|
||||
tableView.delegate = self
|
||||
@@ -583,19 +641,40 @@ final class ViewController: UIViewController {
|
||||
}
|
||||
}
|
||||
|
||||
private func openBook(_ book: DemoBook) {
|
||||
let controller = RDURLReaderController(bookURL: book.fileURL)
|
||||
@discardableResult
|
||||
private func openBook(
|
||||
_ book: DemoBook,
|
||||
configuration: RDEPUBReaderConfiguration = .default,
|
||||
automationPlan: LaunchAutomationPlan? = nil
|
||||
) -> RDURLReaderController {
|
||||
let controller = RDURLReaderController(bookURL: book.fileURL, epubConfiguration: configuration)
|
||||
controller.title = book.title
|
||||
|
||||
if let navigationController {
|
||||
navigationController.pushViewController(controller, animated: true)
|
||||
return
|
||||
} else {
|
||||
let hostController = UINavigationController(rootViewController: controller)
|
||||
hostController.modalPresentationStyle = .fullScreen
|
||||
hostController.view.accessibilityIdentifier = "demo.reader.host"
|
||||
present(hostController, animated: true)
|
||||
}
|
||||
|
||||
let hostController = UINavigationController(rootViewController: controller)
|
||||
hostController.modalPresentationStyle = .fullScreen
|
||||
hostController.view.accessibilityIdentifier = "demo.reader.host"
|
||||
present(hostController, animated: true)
|
||||
if let automationPlan {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 1.2) { [weak controller] in
|
||||
if let pageNumber = automationPlan.pageNumber {
|
||||
_ = controller?.goToDemoPage(pageNumber)
|
||||
}
|
||||
if !automationPlan.displaySequence.isEmpty {
|
||||
controller?.runDemoDisplaySequence(
|
||||
automationPlan.displaySequence,
|
||||
initialPageNumber: nil,
|
||||
stepDelay: automationPlan.stepDelay
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return controller
|
||||
}
|
||||
|
||||
private func currentReaderPageSize() -> CGSize {
|
||||
@@ -619,6 +698,26 @@ final class ViewController: UIViewController {
|
||||
)
|
||||
}
|
||||
|
||||
private func runLaunchAutomationIfNeeded() {
|
||||
guard !didRunLaunchAutomation,
|
||||
let launchAutomationPlan,
|
||||
!books.isEmpty else {
|
||||
return
|
||||
}
|
||||
didRunLaunchAutomation = true
|
||||
|
||||
guard let book = books.first(where: { $0.title.localizedCaseInsensitiveContains(launchAutomationPlan.bookTitleQuery) }) else {
|
||||
print("[ReadViewDemo] automation skipped: missing book matching \(launchAutomationPlan.bookTitleQuery)")
|
||||
return
|
||||
}
|
||||
|
||||
var configuration = RDEPUBReaderConfiguration.default
|
||||
if let displayType = launchAutomationPlan.displayType {
|
||||
configuration.displayType = displayType
|
||||
}
|
||||
_ = openBook(book, configuration: configuration, automationPlan: launchAutomationPlan)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension ViewController: UITableViewDataSource {
|
||||
|
||||
Reference in New Issue
Block a user