Fixed problems with folder select for MCP

This commit is contained in:
2026-03-01 18:00:30 +01:00
parent 98d9ee2b51
commit 65a35cd508
6 changed files with 152 additions and 36 deletions

View File

@@ -42,8 +42,8 @@ struct SettingsView: View {
@State private var openaiKey = ""
@State private var googleKey = ""
@State private var googleEngineID = ""
@State private var showFolderPicker = false
@State private var selectedTab = 0
@State private var isFolderDropTargeted = false
@State private var logLevel: LogLevel = FileLogger.shared.minimumLevel
// Git Sync state
@@ -412,18 +412,21 @@ It's better to admit "I need more information" or "I cannot do that" than to fak
// Folders
VStack(alignment: .leading, spacing: 6) {
sectionHeader("Allowed Folders")
formSection {
// Folder list also a drop target for Finder drags
VStack(spacing: 0) {
if mcpService.allowedFolders.isEmpty {
VStack(spacing: 8) {
Image(systemName: "folder.badge.plus")
.font(.system(size: 32))
.foregroundStyle(.tertiary)
Text("No folders added yet")
.foregroundStyle(isFolderDropTargeted ? AnyShapeStyle(Color.accentColor) : AnyShapeStyle(.tertiary))
Text(isFolderDropTargeted ? "Drop to add folder" : "No folders added yet")
.font(.system(size: 14, weight: .medium))
.foregroundStyle(.secondary)
Text("Click 'Add Folder' below to grant AI access to a folder")
.font(.system(size: 13))
.foregroundStyle(.tertiary)
.foregroundStyle(isFolderDropTargeted ? AnyShapeStyle(Color.accentColor) : AnyShapeStyle(.secondary))
if !isFolderDropTargeted {
Text("Click 'Add Folder' below or drag folders here from Finder")
.font(.system(size: 13))
.foregroundStyle(.tertiary)
}
}
.frame(maxWidth: .infinity)
.padding(.vertical, 24)
@@ -458,32 +461,51 @@ It's better to admit "I need more information" or "I cannot do that" than to fak
}
}
}
}
HStack {
.background(.regularMaterial)
.clipShape(RoundedRectangle(cornerRadius: 10))
.overlay(
RoundedRectangle(cornerRadius: 10)
.stroke(
isFolderDropTargeted ? Color.accentColor : Color.primary.opacity(0.10),
lineWidth: isFolderDropTargeted ? 2 : 0.5
)
)
.onDrop(of: [.fileURL], isTargeted: $isFolderDropTargeted) { providers in
for provider in providers {
_ = provider.loadObject(ofClass: URL.self) { url, _ in
guard let url, url.hasDirectoryPath else { return }
DispatchQueue.main.async {
withAnimation { _ = mcpService.addFolder(url.path) }
}
}
}
return true
}
// Add Folder button
Button {
showFolderPicker = true
let panel = NSOpenPanel()
panel.canChooseFiles = false
panel.canChooseDirectories = true
panel.allowsMultipleSelection = true
panel.prompt = "Add"
panel.message = "Choose folders to allow AI access"
panel.begin { response in
guard response == .OK else { return }
for url in panel.urls {
withAnimation { _ = mcpService.addFolder(url.path) }
}
}
} label: {
HStack(spacing: 4) {
Image(systemName: "plus")
Text("Add Folder...")
}
.font(.system(size: 14))
}
.buttonStyle(.borderless)
Spacer()
}
.padding(.horizontal, 4)
.fileImporter(
isPresented: $showFolderPicker,
allowedContentTypes: [.folder],
allowsMultipleSelection: false
) { result in
if case .success(let urls) = result, let url = urls.first {
if url.startAccessingSecurityScopedResource() {
withAnimation { _ = mcpService.addFolder(url.path) }
url.stopAccessingSecurityScopedResource()
}
Label("Add Folder…", systemImage: "plus")
.font(.system(size: 13, weight: .medium))
.foregroundStyle(.white)
.padding(.horizontal, 14)
.padding(.vertical, 7)
.background(Color.accentColor)
.clipShape(RoundedRectangle(cornerRadius: 8))
}
.buttonStyle(.plain)
}
// Permissions