Skip to content

Commit 7709c0b

Browse files
committed
Adjust UI
1 parent 20b1903 commit 7709c0b

File tree

3 files changed

+136
-63
lines changed

3 files changed

+136
-63
lines changed

Core/Sources/HostApp/AccountSettings/ChatModelManagement/ChatModelEditView.swift

Lines changed: 48 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -101,17 +101,29 @@ struct ChatModelEditView: View {
101101
}
102102
}
103103

104-
func baseURLTextField(prompt: Text?, showIsFullURL: Bool = false) -> some View {
104+
func baseURLTextField<V: View>(
105+
title: String = "Base URL",
106+
prompt: Text?,
107+
@ViewBuilder trailingContent: @escaping () -> V
108+
) -> some View {
105109
BaseURLPicker(
110+
title: title,
106111
prompt: prompt,
107-
showIsFullURL: showIsFullURL,
108112
store: store.scope(
109113
state: \.baseURLSelection,
110114
action: ChatModelEdit.Action.baseURLSelection
111-
)
115+
),
116+
trailingContent: trailingContent
112117
)
113118
}
114119

120+
func baseURLTextField(
121+
title: String = "Base URL",
122+
prompt: Text?
123+
) -> some View {
124+
baseURLTextField(title: title, prompt: prompt, trailingContent: { EmptyView() })
125+
}
126+
115127
var supportsFunctionCallingToggle: some View {
116128
WithViewStore(
117129
store,
@@ -203,7 +215,9 @@ struct ChatModelEditView: View {
203215

204216
@ViewBuilder
205217
var openAI: some View {
206-
baseURLTextField(prompt: Text("https://api.openai.com"))
218+
baseURLTextField(prompt: Text("https://api.openai.com")) {
219+
Text("/v1/chat/completion")
220+
}
207221
apiKeyNamePicker
208222

209223
WithViewStore(
@@ -261,10 +275,34 @@ struct ChatModelEditView: View {
261275

262276
@ViewBuilder
263277
var openAICompatible: some View {
264-
baseURLTextField(
265-
prompt: Text("https://"),
266-
showIsFullURL: true
267-
)
278+
WithViewStore(store.scope(
279+
state: \.baseURLSelection,
280+
action: ChatModelEdit.Action.baseURLSelection
281+
), removeDuplicates: { $0.isFullURL != $1.isFullURL }) { viewStore in
282+
Picker(
283+
selection: viewStore.$isFullURL,
284+
content: {
285+
Text("Base URL").tag(false)
286+
Text("Full URL").tag(true)
287+
},
288+
label: { Text("URL") }
289+
)
290+
.pickerStyle(.segmented)
291+
}
292+
293+
WithViewStore(store, observe: \.isFullURL) { viewStore in
294+
baseURLTextField(
295+
title: "",
296+
prompt: viewStore.state
297+
? Text("https://api.openai.com/v1/chat/completion")
298+
: Text("https://api.openai.com")
299+
) {
300+
if !viewStore.state {
301+
Text("/v1/chat/completion")
302+
}
303+
}
304+
}
305+
268306
apiKeyNamePicker
269307

270308
WithViewStore(
@@ -277,11 +315,11 @@ struct ChatModelEditView: View {
277315
maxTokensTextField
278316
supportsFunctionCallingToggle
279317
}
280-
318+
281319
@ViewBuilder
282320
var googleAI: some View {
283321
apiKeyNamePicker
284-
322+
285323
WithViewStore(
286324
store,
287325
removeDuplicates: { $0.modelName == $1.modelName }

Core/Sources/HostApp/AccountSettings/EmbeddingModelManagement/EmbeddingModelEditView.swift

Lines changed: 46 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -96,17 +96,29 @@ struct EmbeddingModelEditView: View {
9696
}
9797
}
9898

99-
func baseURLTextField(prompt: Text?, showIsFullURL: Bool = false) -> some View {
99+
func baseURLTextField<V: View>(
100+
title: String = "Base URL",
101+
prompt: Text?,
102+
@ViewBuilder trailingContent: @escaping () -> V
103+
) -> some View {
100104
BaseURLPicker(
105+
title: title,
101106
prompt: prompt,
102-
showIsFullURL: showIsFullURL,
103107
store: store.scope(
104108
state: \.baseURLSelection,
105109
action: EmbeddingModelEdit.Action.baseURLSelection
106-
)
110+
),
111+
trailingContent: trailingContent
107112
)
108113
}
109114

115+
func baseURLTextField(
116+
title: String = "Base URL",
117+
prompt: Text?
118+
) -> some View {
119+
baseURLTextField(title: title, prompt: prompt, trailingContent: { EmptyView() })
120+
}
121+
110122
struct MaxTokensTextField: Equatable {
111123
@BindingViewState var maxTokens: Int
112124
var suggestedMaxTokens: Int?
@@ -179,7 +191,9 @@ struct EmbeddingModelEditView: View {
179191

180192
@ViewBuilder
181193
var openAI: some View {
182-
baseURLTextField(prompt: Text("https://api.openai.com"))
194+
baseURLTextField(prompt: Text("https://api.openai.com")) {
195+
Text("/v1/embeddings")
196+
}
183197
apiKeyNamePicker
184198

185199
WithViewStore(
@@ -224,10 +238,34 @@ struct EmbeddingModelEditView: View {
224238

225239
@ViewBuilder
226240
var openAICompatible: some View {
227-
baseURLTextField(
228-
prompt: Text("https://"),
229-
showIsFullURL: true
230-
)
241+
WithViewStore(store.scope(
242+
state: \.baseURLSelection,
243+
action: EmbeddingModelEdit.Action.baseURLSelection
244+
), removeDuplicates: { $0.isFullURL != $1.isFullURL }) { viewStore in
245+
Picker(
246+
selection: viewStore.$isFullURL,
247+
content: {
248+
Text("Base URL").tag(false)
249+
Text("Full URL").tag(true)
250+
},
251+
label: { Text("URL") }
252+
)
253+
.pickerStyle(.segmented)
254+
}
255+
256+
WithViewStore(store, observe: \.isFullURL) { viewStore in
257+
baseURLTextField(
258+
title: "",
259+
prompt: viewStore.state
260+
? Text("https://api.openai.com/v1/embeddings")
261+
: Text("https://api.openai.com")
262+
) {
263+
if !viewStore.state {
264+
Text("/v1/embeddings")
265+
}
266+
}
267+
}
268+
231269
apiKeyNamePicker
232270

233271
WithViewStore(
Lines changed: 42 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,40 @@
11
import ComposableArchitecture
22
import SwiftUI
33

4-
struct BaseURLPicker: View {
4+
struct BaseURLPicker<TrailingContent: View>: View {
5+
let title: String
56
let prompt: Text?
6-
let showIsFullURL: Bool
77
let store: StoreOf<BaseURLSelection>
8+
@ViewBuilder let trailingContent: () -> TrailingContent
89

910
var body: some View {
1011
WithViewStore(store) { viewStore in
11-
Group {
12-
if showIsFullURL {
13-
Picker(
14-
selection: viewStore.$isFullURL,
15-
content: {
16-
Text("Base URL").tag(false)
17-
Text("Full URL").tag(true)
18-
},
19-
label: { Text("URL") }
20-
)
21-
.pickerStyle(.segmented)
22-
}
23-
HStack {
24-
TextField(
25-
showIsFullURL ? "" : "Base URL",
26-
text: viewStore.$baseURL,
27-
prompt: prompt
28-
)
29-
if viewStore.isFullURL == false {
30-
Text("/v1/chat/completions")
31-
}
32-
}
33-
.padding(.trailing)
34-
.overlay(alignment: .trailing) {
35-
Picker(
36-
"",
37-
selection: viewStore.$baseURL,
38-
content: {
39-
if !viewStore.state.availableBaseURLs
40-
.contains(viewStore.state.baseURL),
41-
!viewStore.state.baseURL.isEmpty
42-
{
43-
Text("Custom Value").tag(viewStore.state.baseURL)
44-
}
45-
46-
Text("Empty (Default Value)").tag("")
47-
48-
ForEach(viewStore.state.availableBaseURLs, id: \.self) { baseURL in
49-
Text(baseURL).tag(baseURL)
12+
HStack {
13+
TextField(title, text: viewStore.$baseURL, prompt: prompt)
14+
.overlay(alignment: .trailing) {
15+
Picker(
16+
"",
17+
selection: viewStore.$baseURL,
18+
content: {
19+
if !viewStore.state.availableBaseURLs
20+
.contains(viewStore.state.baseURL),
21+
!viewStore.state.baseURL.isEmpty
22+
{
23+
Text("Custom Value").tag(viewStore.state.baseURL)
24+
}
25+
26+
Text("Empty (Default Value)").tag("")
27+
28+
ForEach(viewStore.state.availableBaseURLs, id: \.self) { baseURL in
29+
Text(baseURL).tag(baseURL)
30+
}
5031
}
51-
}
52-
)
53-
.frame(width: 20)
54-
}
32+
)
33+
.frame(width: 20)
34+
}
35+
36+
trailingContent()
37+
.foregroundStyle(.secondary)
5538
}
5639
.onAppear {
5740
viewStore.send(.appear)
@@ -60,3 +43,17 @@ struct BaseURLPicker: View {
6043
}
6144
}
6245

46+
extension BaseURLPicker where TrailingContent == EmptyView {
47+
init(
48+
title: String,
49+
prompt: Text? = nil,
50+
store: StoreOf<BaseURLSelection>
51+
) {
52+
self.init(
53+
title: title,
54+
prompt: prompt,
55+
store: store,
56+
trailingContent: { EmptyView() }
57+
)
58+
}
59+
}

0 commit comments

Comments
 (0)