Add source editing to ingest
All checks were successful
CI / build-and-deploy (push) Successful in 25s

This commit is contained in:
Krishna Kumar
2026-07-02 16:35:02 -05:00
parent f7735431a8
commit 8e1d94a4ea
4 changed files with 119 additions and 1 deletions

View File

@@ -12,6 +12,7 @@ struct SourcesView: View {
@State private var showTextImport = false
@State private var showFileImporter = false
@State private var selectedSource: IngestedSource?
@State private var editingSource: IngestedSource?
@State private var showFullPlayer = false
private var results: [IngestedSource] {
@@ -98,6 +99,13 @@ struct SourcesView: View {
fileURL: library.fileURL(for: source),
podcastCached: podcastCached(for: source),
podcastGenerating: podcastGenerator.isGenerating(source.podcastURL),
onEdit: {
selectedSource = nil
Task {
try? await Task.sleep(for: .milliseconds(250))
editingSource = source
}
},
onPodcast: {
selectedSource = nil
Task {
@@ -107,6 +115,9 @@ struct SourcesView: View {
}
)
}
.sheet(item: $editingSource) { source in
EditSourceView(source: source, library: library)
}
.sheet(isPresented: $showFullPlayer) {
PodcastPlayerView(
vm: podcastPlayer,
@@ -272,11 +283,76 @@ private struct ImportTextSourceView: View {
}
}
private struct EditSourceView: View {
let source: IngestedSource
@Bindable var library: IngestedSourceLibrary
@Environment(\.dismiss) private var dismiss
@State private var title: String
@State private var bodyText: String
@State private var tagsText: String
init(source: IngestedSource, library: IngestedSourceLibrary) {
self.source = source
self.library = library
_title = State(initialValue: source.title)
_bodyText = State(initialValue: source.bodyText)
_tagsText = State(initialValue: source.tags.joined(separator: ", "))
}
var body: some View {
NavigationStack {
Form {
Section("Title") {
TextField("Optional", text: $title)
}
Section {
TextEditor(text: $bodyText)
.frame(minHeight: 220)
.textInputAutocapitalization(.sentences)
} header: {
Text(source.kind == .text ? "Text" : "Extracted Text")
} footer: {
if source.kind != .text {
Text("Editing extracted text does not modify the original file.")
}
}
Section {
TextField("comma separated", text: $tagsText)
.textInputAutocapitalization(.never)
.autocorrectionDisabled()
} header: {
Text("Tags")
} footer: {
Text("Separate tags with commas")
}
}
.navigationTitle("Edit Source")
.navigationBarTitleDisplayMode(.inline)
.toolbar {
ToolbarItem(placement: .cancellationAction) {
Button("Cancel") { dismiss() }
}
ToolbarItem(placement: .confirmationAction) {
Button("Save") {
library.update(source, title: title, bodyText: bodyText, tags: tagsText.parsedTags)
dismiss()
}
.disabled(bodyText.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty)
}
}
}
}
}
private struct SourceDetailView: View {
let source: IngestedSource
let fileURL: URL?
let podcastCached: Bool
let podcastGenerating: Bool
let onEdit: () -> Void
let onPodcast: () -> Void
@State private var previewURL: URL?
@@ -343,6 +419,15 @@ private struct SourceDetailView: View {
}
.navigationTitle("Source")
.navigationBarTitleDisplayMode(.inline)
.toolbar {
ToolbarItem(placement: .topBarTrailing) {
Button {
onEdit()
} label: {
Label("Edit", systemImage: "pencil")
}
}
}
}
.quickLookPreview($previewURL)
}