feat: add "阅读原文件" button to KnowledgeDetailPage
Blue gradient button at bottom of plain text content view. Writes content to temp .md file and navigates to MaterialReaderView, which triggers reading event collection. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
def8c4c93a
commit
1c0a625192
@ -1109,6 +1109,28 @@ struct KnowledgeDetailPage: View {
|
||||
.padding(16).background(Color.zxFill004).clipShape(RoundedRectangle(cornerRadius: 14))
|
||||
}
|
||||
Text(content).font(.system(size: 14)).foregroundColor(Color.zxF0).lineSpacing(6)
|
||||
|
||||
// 阅读原文件 button
|
||||
if let path = vm.localPath ?? (try? writeTempFile(content: content, itemId: item.id)), let mt = vm.detectedType ?? detectTypeFromContent(content, sourceType: item.sourceType) {
|
||||
NavigationLink(value: Route.materialReader(
|
||||
materialId: item.id,
|
||||
filePath: path,
|
||||
materialType: mt,
|
||||
knowledgeBaseId: item.knowledgeBaseId,
|
||||
title: item.title
|
||||
)) {
|
||||
HStack(spacing: 8) {
|
||||
Image(systemName: "book")
|
||||
Text("阅读原文件")
|
||||
}
|
||||
.font(.system(size: 15, weight: .bold))
|
||||
.foregroundColor(.white)
|
||||
.frame(maxWidth: .infinity).frame(height: 48)
|
||||
.background(LinearGradient(colors: [Color.zxPurple, Color.zxAccent], startPoint: .leading, endPoint: .trailing))
|
||||
.clipShape(RoundedRectangle(cornerRadius: 14))
|
||||
}
|
||||
.padding(.top, 8)
|
||||
}
|
||||
}.padding(.horizontal, 20).padding(.top, 8).padding(.bottom, 100)
|
||||
}.scrollIndicators(.hidden)
|
||||
}
|
||||
@ -1452,3 +1474,30 @@ struct EditKnowledgePage: View {
|
||||
}.navigationBarTitleDisplayMode(.inline).toolbarBackground(.hidden, for: .navigationBar).toolbar(.hidden, for: .tabBar)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Helpers
|
||||
|
||||
private func writeTempFile(content: String, itemId: String) throws -> String {
|
||||
let dir = FileManager.default.temporaryDirectory
|
||||
let url = dir.appendingPathComponent("kd_text_\(itemId).md")
|
||||
try content.write(to: url, atomically: true, encoding: .utf8)
|
||||
return url.path
|
||||
}
|
||||
|
||||
private func detectTypeFromContent(_ content: String, sourceType: String?) -> MaterialType? {
|
||||
if let st = sourceType {
|
||||
switch st.lowercased() {
|
||||
case "markdown", "md": return .markdown
|
||||
case "txt", "text": return .text
|
||||
case "pdf": return .pdf
|
||||
case "epub": return .epub
|
||||
case "docx", "doc": return .word
|
||||
case "xlsx", "xls": return .excel
|
||||
case "pptx", "ppt": return .powerPoint
|
||||
default: break
|
||||
}
|
||||
}
|
||||
// Detect from content
|
||||
if content.hasPrefix("#") || content.contains("```") { return .markdown }
|
||||
return .text
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user