import Foundation final class RDEPUBReaderLoadCoordinator { private unowned let context: RDEPUBReaderContext init(context: RDEPUBReaderContext) { self.context = context } func startInitialLoadIfNeeded() { guard let controller = context.controller, let readerView = context.readerView, !controller.didStartInitialLoad, readerView.bounds.width > 0, readerView.bounds.height > 0 else { return } controller.didStartInitialLoad = true loadPublication() } func loadPublication() { guard let controller = context.controller else { return } context.showLoading() let loadToken = UUID() context.paginationToken = loadToken DispatchQueue.global(qos: .userInitiated).async { [weak controller] in guard let controller else { return } let parser = self.context.makeParser() do { try parser.parse(epubURL: controller.epubURL) let publication = parser.makePublication() let bookIdentifier = parser.metadata.identifier ?? controller.epubURL.lastPathComponent let restoreLocation = controller.persistence?.loadLocation(for: bookIdentifier) let bookmarks = controller.persistence?.loadBookmarks(for: bookIdentifier) ?? [] let highlights = controller.persistence?.loadHighlights(for: bookIdentifier) ?? [] DispatchQueue.main.async { guard self.context.paginationToken == loadToken else { return } self.context.runtime?.applyParsedPublication( parser: parser, publication: publication, bookIdentifier: bookIdentifier, restoreLocation: restoreLocation, bookmarks: bookmarks, highlights: highlights ) } } catch { DispatchQueue.main.async { guard self.context.paginationToken == loadToken else { return } self.context.handle(error: error) } } } } func applyParsedPublication( parser: RDEPUBParser, publication: RDEPUBPublication, bookIdentifier: String, restoreLocation: RDEPUBLocation?, bookmarks: [RDEPUBBookmark], highlights: [RDEPUBHighlight] ) { guard let controller = context.controller else { return } context.parser = parser context.publication = publication context.currentBookIdentifier = bookIdentifier context.activeBookmarks = bookmarks context.activeHighlights = highlights context.readingSession = RDEPUBReadingSession(publication: publication) context.readingSession?.transition(to: .loading) controller.title = parser.metadata.title.isEmpty ? controller.epubURL.deletingPathExtension().lastPathComponent : parser.metadata.title controller.applyReaderViewConfiguration() context.updateReaderChrome() controller.delegate?.epubReader(controller, didOpen: publication) context.runtime?.paginatePublication(restoreLocation: restoreLocation) } }