Full generation, file type cleanup

This commit is contained in:
Christoph Hagen
2024-12-25 18:06:05 +01:00
parent 41887a1401
commit 1e4682dad1
56 changed files with 1577 additions and 1103 deletions

View File

@ -80,7 +80,8 @@ struct AddPageView: View {
english: .init(content: content,
urlString: "page",
title: "A Title"),
tags: [])
tags: [],
requiredFiles: [])
content.add(page)
selectedPage = page
dismissSheet()

View File

@ -4,6 +4,9 @@ import HighlightedTextEditor
struct LocalizedPageContentView: View {
@EnvironmentObject
var content: Content
let pageId: String
let language: ContentLanguage
@ -11,9 +14,6 @@ struct LocalizedPageContentView: View {
@ObservedObject
var page: LocalizedPage
@State
private var isGeneratingWebsite = false
@State
private var pageContent: String = ""
@ -21,7 +21,7 @@ struct LocalizedPageContentView: View {
private var pageContentUsedForGeneration: String = ""
@State
private var generationResults = PageGenerationResults()
private var generationResults: PageGenerationResults?
@State
private var didChangeContent = false
@ -47,10 +47,16 @@ struct LocalizedPageContentView: View {
}
Button(action: checkContent) {
Text("Check")
}.disabled(content.isGeneratingWebsite)
if content.isGeneratingWebsite {
ProgressView()
.frame(height: 15)
}
Spacer()
}
PageContentResultsView(results: generationResults)
if let generationResults {
PageContentResultsView(results: generationResults)
}
HighlightedTextEditor(
text: $pageContent,
highlightRules: .markdown)
@ -65,9 +71,19 @@ struct LocalizedPageContentView: View {
private func loadContent() {
let language = language
guard page.content.storage.hasPageContent(for: pageId, language: language) else {
pageContent = "New file"
DispatchQueue.main.async {
didChangeContent = false
}
return
}
guard let content = page.content.storage.pageContent(for: pageId, language: language) else {
print("Failed to load page content")
pageContent = "Failed to load"
DispatchQueue.main.async {
didChangeContent = false
}
return
}
guard content != "" else {
@ -105,15 +121,14 @@ struct LocalizedPageContentView: View {
guard content != pageContentUsedForGeneration else {
return
}
isGeneratingWebsite = true
DispatchQueue.global(qos: .background).async {
let generator = PageContentParser(content: page.content, language: language)
_ = generator.generatePage(from: content)
DispatchQueue.main.async {
self.generationResults = generator.results
isGeneratingWebsite = false
}
guard let page = self.content.page(pageId) else {
return
}
guard !self.content.isGeneratingWebsite else {
return
}
self.content.check(content: content, of: page, for: language) {
self.generationResults = $0
}
}
}

View File

@ -67,17 +67,22 @@ struct PageContentResultsView: View {
@ObservedObject
var results: PageGenerationResults
#warning("Rework to only show a single popup will all files, and indicate missing ones")
private var totalFileCount: Int {
results.usedFiles.count + results.missingFiles.count + results.missingLinkedFiles.count
}
var body: some View {
HStack {
TextWithPopup(
symbol: .photoOnRectangleAngled,
text: "\(results.files.count + results.missingFiles.count) images and files",
items: results.files.sorted().map { $0.id })
text: "\(totalFileCount) images and files",
items: results.usedFiles.sorted().map { $0.id })
.foregroundStyle(.secondary)
TextWithPopup(
symbol: .docBadgePlus,
text: "\(results.linkedPages.count + results.missingPages.count) page links",
text: "\(results.linkedPages.count + results.missingLinkedPages.count) page links",
items: results.linkedPages.sorted().map { $0.localized(in: language).title })
.foregroundStyle(.secondary)
@ -87,18 +92,18 @@ struct PageContentResultsView: View {
items: results.externalLinks.sorted())
.foregroundStyle(.secondary)
if !results.missingPages.isEmpty {
if !results.missingLinkedPages.isEmpty {
TextWithPopup(
symbol: .exclamationmarkTriangleFill,
text: "\(results.missingPages.count) missing pages",
items: results.missingPages.sorted())
text: "\(results.missingLinkedPages.count) missing pages",
items: results.missingLinkedPages.keys.sorted())
.foregroundStyle(.red)
}
if !results.missingFiles.isEmpty {
TextWithPopup(
symbol: .exclamationmarkTriangleFill,
text: "\(results.missingFiles.count) missing files",
items: results.missingFiles.sorted())
items: results.missingFiles.keys.sorted())
.foregroundStyle(.red)
}
if !results.invalidCommands.isEmpty {
@ -111,7 +116,3 @@ struct PageContentResultsView: View {
}
}
}
#Preview {
PageContentResultsView(results: .init())
}

View File

@ -13,12 +13,21 @@ struct PageDetailView: View {
private var page: Page
@State
private var didGenerateWebsite: Bool?
private var showFileSelectionSheet = false
init(page: Page) {
self.page = page
}
private var requiredFilesText: String {
switch page.requiredFiles.count {
case 0: return "No files"
case 1: return "1 file"
default: return "\(page.requiredFiles.count) files"
}
}
#warning("Show info on page generation")
var body: some View {
ScrollView {
VStack(alignment: .leading) {
@ -30,17 +39,17 @@ struct PageDetailView: View {
Text("Generate")
}
.disabled(content.isGeneratingWebsite)
switch didGenerateWebsite {
case .none:
Image(systemSymbol: .questionmarkCircleFill)
.foregroundStyle(.gray)
case .some(true):
Image(systemSymbol: .checkmarkCircleFill)
.foregroundStyle(.green)
case .some(false):
Image(systemSymbol: .xmarkCircleFill)
.foregroundStyle(.red)
}
// switch didGenerateWebsite {
// case .none:
// Image(systemSymbol: .questionmarkCircleFill)
// .foregroundStyle(.gray)
// case .some(true):
// Image(systemSymbol: .checkmarkCircleFill)
// .foregroundStyle(.green)
// case .some(false):
// Image(systemSymbol: .xmarkCircleFill)
// .foregroundStyle(.red)
// }
}
IdPropertyView(
id: $page.id,
@ -72,6 +81,24 @@ struct PageDetailView: View {
footer: "The date when the page content ended")
.disabled(page.isExternalUrl)
GenericPropertyView(
title: "Required files",
footer: "The additional files required by the page") {
HStack {
Image(systemSymbol: .squareAndPencilCircleFill)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(height: 20)
Text(requiredFilesText)
Spacer()
}
.padding(.vertical, 8)
.contentShape(Rectangle())
.onTapGesture {
showFileSelectionSheet = true
}
}
LocalizedPageDetailView(
isExternalPage: page.isExternalUrl,
page: page.localized(in: language))
@ -79,14 +106,14 @@ struct PageDetailView: View {
}
.padding()
}
.sheet(isPresented: $showFileSelectionSheet) {
MultiFileSelectionView(selectedFiles: $page.requiredFiles, insertSorted: true)
}
}
private func generate() {
DispatchQueue.global(qos: .userInitiated).async {
let success = content.generateFeed()
DispatchQueue.main.async {
didGenerateWebsite = success
}
content.generatePage(page)
}
}
}