import Foundation extension Content { private func convert(_ tag: LocalizedTagFile, images: [String : FileResource]) -> LocalizedTag { LocalizedTag( content: self, urlComponent: tag.urlComponent, name: tag.name, linkPreviewTitle: tag.linkPreviewTitle, linkPreviewDescription: tag.linkPreviewDescription, linkPreviewImage: tag.linkPreviewImage.map { images[$0] }, originalUrl: tag.originalURL) } private func convert(_ page: LocalizedPageFile, images: [String : FileResource]) -> LocalizedPage { LocalizedPage( content: self, urlString: page.url, title: page.title, lastModified: page.lastModifiedDate, originalUrl: page.originalURL, linkPreviewImage: page.linkPreviewImage.map { images[$0] }, linkPreviewTitle: page.linkPreviewTitle, linkPreviewDescription: page.linkPreviewDescription, hideTitle: page.hideTitle ?? false) } func loadFromDisk() throws { guard storage.contentScope != nil else { print("Storage not initialized, not loading content") throw StorageAccessError.noBookmarkData } let settings = storage.loadSettings() ?? .default guard let tagData = storage.loadAllTags() else { print("Failed to load file tags") return } if tagData.isEmpty { print("No tags loaded") } guard let pagesData = storage.loadAllPages() else { print("Failed to load file pages") return } if pagesData.isEmpty { print("No pages loaded") } guard let postsData = storage.loadAllPosts() else { print("Failed to load file posts") return } if postsData.isEmpty { print("No posts loaded") } guard let fileList = storage.loadAllFiles() else { print("Failed to load file list") return } if fileList.isEmpty { print("No files loaded") } print("Loaded data from disk, processing...") // All data loaded from storage, start constructing the data model let files: [String : FileResource] = fileList.reduce(into: [:]) { (files, data) in let fileId = data.key let fileData = data.value.data let isExternal = data.value.isExternal files[fileId] = FileResource(content: self, id: fileId, file: fileData, isExternalFile: isExternal) } let images = files.filter { $0.value.type.isImage } let tags = tagData.reduce(into: [:]) { (tags, data) in tags[data.key] = Tag( content: self, id: data.value.id, isVisible: data.value.isVisible, german: convert(data.value.german, images: images), english: convert(data.value.english, images: images)) } let pages: [String : Page] = loadPages(pagesData, tags: tags, files: files) let posts: [String : Post] = postsData.reduce(into: [:]) { dict, data in let (postId, post) = data let linkedPage = post.linkedPageId.map { pages[$0] } let german = LocalizedPost(content: self, file: post.german, images: images) let english = LocalizedPost(content: self, file: post.english, images: images) dict[postId] = Post( content: self, id: postId, isDraft: post.isDraft, createdDate: post.createdDate, startDate: post.startDate, endDate: post.endDate, tags: post.tags.map { tags[$0]! }, german: german, english: english, linkedPage: linkedPage) } let tagOverview = settings.tagOverview.map { file in TagOverviewPage( content: self, german: .init(content: self, file: file.german, image: file.german.linkPreviewImage.map { files[$0] }), english: .init(content: self, file: file.english, image: file.english.linkPreviewImage.map { files[$0] })) } self.tags = tags.values.sorted() self.pages = pages.values.sorted(ascending: false) { $0.startDate } self.files = files.values.sorted { $0.id } self.posts = posts.values.sorted(ascending: false) { $0.startDate } self.tagOverview = tagOverview self.settings = .init(file: settings, files: files) { raw in #warning("Notify about missing links") guard let type = ItemType(rawValue: raw, posts: posts, pages: pages, tags: tags) else { return nil } switch type { case .general: return nil case .post(let post): return post case .feed: return nil // TODO: Provide feed object case .page(let page): return page case .tagPage(let tag): return tag case .tagOverview: return tagOverview } } print("Content loaded") } private func loadPages(_ pagesData: [String : PageFile], tags: [String : Tag], files: [String : FileResource]) -> [String : Page] { pagesData.reduce(into: [:]) { pages, data in let (pageId, page) = data pages[pageId] = Page( content: self, id: pageId, externalLink: page.externalLink, isDraft: page.isDraft, createdDate: page.createdDate, hideDate: page.hideDate ?? false, startDate: page.startDate, endDate: page.endDate, german: convert(page.german, images: files), english: convert(page.english, images: files), tags: page.tags.compactMap { tags[$0] }, requiredFiles: page.requiredFiles?.compactMap { files[$0] } ?? []) } } }