feat: LLM 设置窗口添加「从另一个配置复制」按钮

This commit is contained in:
JOJO 2026-04-24 22:52:53 +08:00
parent 7dc0d8ce26
commit 847ae72e49

View File

@ -9,6 +9,7 @@ final class SettingsWindow: NSWindow {
private let modelField: NSTextField private let modelField: NSTextField
private let testButton: NSButton private let testButton: NSButton
private let saveButton: NSButton private let saveButton: NSButton
private let copyFromOtherButton: NSButton
private let statusLabel: NSTextField private let statusLabel: NSTextField
init(mode: LLMMode) { init(mode: LLMMode) {
@ -19,9 +20,10 @@ final class SettingsWindow: NSWindow {
modelField = NSTextField(frame: .zero) modelField = NSTextField(frame: .zero)
testButton = NSButton(title: "Test", target: nil, action: nil) testButton = NSButton(title: "Test", target: nil, action: nil)
saveButton = NSButton(title: "Save", target: nil, action: nil) saveButton = NSButton(title: "Save", target: nil, action: nil)
copyFromOtherButton = NSButton(title: "", target: nil, action: nil)
statusLabel = NSTextField(labelWithString: "") statusLabel = NSTextField(labelWithString: "")
let windowRect = NSRect(x: 0, y: 0, width: 420, height: 280) let windowRect = NSRect(x: 0, y: 0, width: 420, height: 320)
super.init( super.init(
contentRect: windowRect, contentRect: windowRect,
styleMask: [.titled, .closable, .miniaturizable], styleMask: [.titled, .closable, .miniaturizable],
@ -111,6 +113,13 @@ final class SettingsWindow: NSWindow {
saveButton.target = self saveButton.target = self
saveButton.action = #selector(saveConfig) saveButton.action = #selector(saveConfig)
let otherModeName = mode == .input ? "AI 助手" : "语音输入"
copyFromOtherButton.title = "从「\(otherModeName)」复制配置"
copyFromOtherButton.bezelStyle = .rounded
copyFromOtherButton.translatesAutoresizingMaskIntoConstraints = false
copyFromOtherButton.target = self
copyFromOtherButton.action = #selector(copyFromOther)
statusLabel.font = .systemFont(ofSize: 11) statusLabel.font = .systemFont(ofSize: 11)
statusLabel.textColor = .secondaryLabelColor statusLabel.textColor = .secondaryLabelColor
statusLabel.alignment = .center statusLabel.alignment = .center
@ -136,6 +145,7 @@ final class SettingsWindow: NSWindow {
content.addSubview(grid) content.addSubview(grid)
content.addSubview(buttonStack) content.addSubview(buttonStack)
content.addSubview(copyFromOtherButton)
content.addSubview(statusLabel) content.addSubview(statusLabel)
NSLayoutConstraint.activate([ NSLayoutConstraint.activate([
@ -147,7 +157,10 @@ final class SettingsWindow: NSWindow {
buttonStack.centerXAnchor.constraint(equalTo: content.centerXAnchor), buttonStack.centerXAnchor.constraint(equalTo: content.centerXAnchor),
buttonStack.widthAnchor.constraint(equalToConstant: 220), buttonStack.widthAnchor.constraint(equalToConstant: 220),
statusLabel.topAnchor.constraint(equalTo: buttonStack.bottomAnchor, constant: 12), copyFromOtherButton.topAnchor.constraint(equalTo: buttonStack.bottomAnchor, constant: 10),
copyFromOtherButton.centerXAnchor.constraint(equalTo: content.centerXAnchor),
statusLabel.topAnchor.constraint(equalTo: copyFromOtherButton.bottomAnchor, constant: 10),
statusLabel.centerXAnchor.constraint(equalTo: content.centerXAnchor), statusLabel.centerXAnchor.constraint(equalTo: content.centerXAnchor),
statusLabel.widthAnchor.constraint(equalToConstant: 380) statusLabel.widthAnchor.constraint(equalToConstant: 380)
]) ])
@ -194,6 +207,19 @@ final class SettingsWindow: NSWindow {
} }
} }
@objc private func copyFromOther() {
let otherMode: LLMMode = mode == .input ? .assist : .input
let config = Config.shared.getLLMConfig(for: otherMode)
baseURLField.stringValue = config.baseURL
apiKeyField.stringValue = config.apiKey
modelField.stringValue = config.model
statusLabel.stringValue = "✅ 已复制「\(otherMode == .input ? "语音输入" : "AI 助手")」的配置"
statusLabel.textColor = .systemGreen
DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) { [weak self] in
self?.statusLabel.stringValue = ""
}
}
@objc private func saveConfig() { @objc private func saveConfig() {
let url = baseURLField.stringValue.trimmingCharacters(in: CharacterSet(charactersIn: "/")) let url = baseURLField.stringValue.trimmingCharacters(in: CharacterSet(charactersIn: "/"))
let key = apiKeyField.stringValue let key = apiKeyField.stringValue