From cdf8a22c4b27b0a4af4331d96a4aca6ee42f0c6d Mon Sep 17 00:00:00 2001 From: Kaede Akino Date: Wed, 16 Sep 2026 21:35:18 +0800 Subject: [PATCH] Use as hint --- Frameworks/Resources/Localizable.xcstrings | 1 + .../ModelProviderConnectionFields.swift | 5 ++--- .../Settings/ModelProviderSettings.swift | 2 +- TFM/Features/Settings/SettingsPageView.swift | 6 ++--- TFMTests/SettingsNavigationTests.swift | 22 ++++++++++++++----- 5 files changed, 23 insertions(+), 13 deletions(-) diff --git a/Frameworks/Resources/Localizable.xcstrings b/Frameworks/Resources/Localizable.xcstrings index 625bcb0b..6b9807ef 100644 --- a/Frameworks/Resources/Localizable.xcstrings +++ b/Frameworks/Resources/Localizable.xcstrings @@ -14507,6 +14507,7 @@ } }, "New Provider" : { + "extractionState" : "manual", "localizations" : { "zh-Hans" : { "stringUnit" : { diff --git a/Frameworks/TermindPresentation/ModelProviderConnectionFields.swift b/Frameworks/TermindPresentation/ModelProviderConnectionFields.swift index 61a77868..3395aa21 100644 --- a/Frameworks/TermindPresentation/ModelProviderConnectionFields.swift +++ b/Frameworks/TermindPresentation/ModelProviderConnectionFields.swift @@ -16,9 +16,8 @@ public struct ModelProviderConnectionFields: View { public var body: some View { Section { LabeledContent("Name") { - TextField("Name", text: $name.singleLineText, axis: .horizontal).singleLinePaste().lineLimit(1) - .labelsHidden() - .multilineTextAlignment(.trailing) + TextField("Name", text: $name.singleLineText, prompt: Text("New Provider"), axis: .horizontal) + .singleLinePaste().lineLimit(1).labelsHidden().multilineTextAlignment(.trailing) } Toggle("Enabled", isOn: $isEnabled) Picker("API Type", selection: $endpoint.apiType) { diff --git a/TFM/Features/Settings/ModelProviderSettings.swift b/TFM/Features/Settings/ModelProviderSettings.swift index ad176ab5..6b89a8a2 100644 --- a/TFM/Features/Settings/ModelProviderSettings.swift +++ b/TFM/Features/Settings/ModelProviderSettings.swift @@ -26,7 +26,7 @@ struct ModelProviderSettings: View { // there is one code path for "new" and "edit" and no half-built // provider living in a view's `@State`. Cancelling takes it back // out again — which is what `isNew` below is for. - let provider = ModelProvider(name: String(localized: "New Provider")) + let provider = ModelProvider(name: "") app.aiConfiguration.upsert(provider) edit(provider.id, true) } diff --git a/TFM/Features/Settings/SettingsPageView.swift b/TFM/Features/Settings/SettingsPageView.swift index 355fca21..cd84d49b 100644 --- a/TFM/Features/Settings/SettingsPageView.swift +++ b/TFM/Features/Settings/SettingsPageView.swift @@ -297,13 +297,11 @@ private struct SettingsCategoryRow: View { enum SettingsDraftPolicy { static func shouldDiscard(_ provider: ModelProvider) -> Bool { - let hasDefaultName = - provider.name.trimmingCharacters(in: .whitespacesAndNewlines) - == String(localized: "New Provider") + let hasEmptyName = provider.name.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty let hasConfiguration = !provider.inferenceURL.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty || provider.hasCredential || !provider.models.isEmpty - return hasDefaultName && !hasConfiguration + return hasEmptyName && !hasConfiguration } static func shouldDiscard(_ server: MCPServer) -> Bool { diff --git a/TFMTests/SettingsNavigationTests.swift b/TFMTests/SettingsNavigationTests.swift index 9931f957..dbf8a22a 100644 --- a/TFMTests/SettingsNavigationTests.swift +++ b/TFMTests/SettingsNavigationTests.swift @@ -121,19 +121,31 @@ struct SettingsNavigationTests { #expect(window.sidebarMode == .navigation) } - @Test - func emptyProviderDraftIsDiscarded() { - let provider = ModelProvider(name: String(localized: "New Provider")) + @Test(arguments: ["", " \t\n "]) + func emptyProviderDraftIsDiscarded(name: String) { + var provider = ModelProvider(name: name) + provider.inferenceURL = " \t\n " #expect(SettingsDraftPolicy.shouldDiscard(provider)) } @Test func configuredProviderDraftIsKept() { - var provider = ModelProvider(name: String(localized: "New Provider")) + var provider = ModelProvider(name: "") provider.inferenceURL = "https://example.com/v1/chat/completions" #expect(!SettingsDraftPolicy.shouldDiscard(provider)) - provider = ModelProvider(name: "Work") + provider = ModelProvider(name: "") + provider.credentialRef = "test-credential" + #expect(!SettingsDraftPolicy.shouldDiscard(provider)) + + provider = ModelProvider(name: "") + provider.models = [AIModel(id: "test-model")] + #expect(!SettingsDraftPolicy.shouldDiscard(provider)) + } + + @Test(arguments: ["Work", "New Provider", String(localized: "New Provider")]) + func namedProviderDraftIsKept(name: String) { + let provider = ModelProvider(name: name) #expect(!SettingsDraftPolicy.shouldDiscard(provider)) }