mirror of
https://github.com/Aminark/legado-ios.git
synced 2026-10-24 21:01:22 +08:00
feat: 支持 EPUB 阅读并改善规则兼容与阅读稳定性
支持 EPUB 2/3 导入、目录、封面和章节插图,保留本地书管理与阅读进度。 修复 JSON 模板、动态替换与请求参数兼容,以及 RSS 翻页和连续滚动定位。 更新编辑器工具栏和回归测试,发布版本为 0.1.12(build 18)。
This commit is contained in:
+11
-10
@@ -207,7 +207,7 @@ struct ReadingPhotoPickerController: UIViewControllerRepresentable {
|
||||
}
|
||||
}
|
||||
|
||||
private struct ReadingTXTFileImporterModifier: ViewModifier {
|
||||
private struct ReadingLocalBookFileImporterModifier: ViewModifier {
|
||||
@Binding var isPresented: Bool
|
||||
let onFiles: ([LocalBookImportFile]) -> Void
|
||||
let onError: (Error) -> Void
|
||||
@@ -219,7 +219,7 @@ private struct ReadingTXTFileImporterModifier: ViewModifier {
|
||||
pickerHasDismissed = true
|
||||
deliverFilesWhenReady()
|
||||
}) {
|
||||
ReadingTXTFilePicker { files in
|
||||
ReadingLocalBookFilePicker { files in
|
||||
pickedFiles = files
|
||||
isPresented = false
|
||||
deliverFilesWhenReady()
|
||||
@@ -239,7 +239,7 @@ private struct ReadingTXTFileImporterModifier: ViewModifier {
|
||||
guard pickerHasDismissed, !pickedFiles.isEmpty else { return }
|
||||
let files = pickedFiles
|
||||
pickedFiles = []
|
||||
guard files.allSatisfy({ $0.url.pathExtension.lowercased() == "txt" && !$0.url.hasDirectoryPath }) else {
|
||||
guard files.allSatisfy({ LocalBookService.supports($0.url) && !$0.url.hasDirectoryPath }) else {
|
||||
onError(LocalBookError.unsupportedFormat)
|
||||
return
|
||||
}
|
||||
@@ -247,15 +247,16 @@ private struct ReadingTXTFileImporterModifier: ViewModifier {
|
||||
}
|
||||
}
|
||||
|
||||
private struct ReadingTXTFilePicker: UIViewControllerRepresentable {
|
||||
private struct ReadingLocalBookFilePicker: UIViewControllerRepresentable {
|
||||
let onPick: @MainActor ([LocalBookImportFile]) -> Void
|
||||
let onCancel: @MainActor () -> Void
|
||||
|
||||
func makeCoordinator() -> Coordinator { Coordinator(parent: self) }
|
||||
|
||||
func makeUIViewController(context: Context) -> UIDocumentPickerViewController {
|
||||
// Plain text includes UTF-8/UTF-16 TXT, while .text and .data also allow JSON.
|
||||
let picker = UIDocumentPickerViewController(forOpeningContentTypes: [.plainText], asCopy: true)
|
||||
// Keep source JSON out of the local-book picker.
|
||||
let epub = UTType(filenameExtension: "epub") ?? UTType(importedAs: "org.idpf.epub-container")
|
||||
let picker = UIDocumentPickerViewController(forOpeningContentTypes: [.plainText, epub], asCopy: true)
|
||||
picker.allowsMultipleSelection = true
|
||||
picker.shouldShowFileExtensions = true
|
||||
picker.delegate = context.coordinator
|
||||
@@ -266,9 +267,9 @@ private struct ReadingTXTFilePicker: UIViewControllerRepresentable {
|
||||
|
||||
@MainActor
|
||||
final class Coordinator: NSObject, UIDocumentPickerDelegate {
|
||||
let parent: ReadingTXTFilePicker
|
||||
let parent: ReadingLocalBookFilePicker
|
||||
|
||||
init(parent: ReadingTXTFilePicker) { self.parent = parent }
|
||||
init(parent: ReadingLocalBookFilePicker) { self.parent = parent }
|
||||
|
||||
func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) { parent.onCancel() }
|
||||
|
||||
@@ -281,12 +282,12 @@ private struct ReadingTXTFilePicker: UIViewControllerRepresentable {
|
||||
enum ReadingSheetDetent { case medium, large }
|
||||
|
||||
extension View {
|
||||
func readingTXTFileImporter(
|
||||
func readingLocalBookFileImporter(
|
||||
isPresented: Binding<Bool>,
|
||||
onFiles: @escaping ([LocalBookImportFile]) -> Void,
|
||||
onError: @escaping (Error) -> Void
|
||||
) -> some View {
|
||||
modifier(ReadingTXTFileImporterModifier(isPresented: isPresented, onFiles: onFiles, onError: onError))
|
||||
modifier(ReadingLocalBookFileImporterModifier(isPresented: isPresented, onFiles: onFiles, onError: onError))
|
||||
}
|
||||
|
||||
func readingPhotoPicker(
|
||||
|
||||
Reference in New Issue
Block a user