Skip to content

Commit ea3ab15

Browse files
committed
refactor
1 parent b9be729 commit ea3ab15

File tree

8 files changed

+71
-73
lines changed

8 files changed

+71
-73
lines changed

Examples/Sources/ChatbotExample/ChatbotApp.swift

Lines changed: 17 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -10,52 +10,30 @@ import SwiftCrossUI
1010
@main
1111
@HotReloadable
1212
struct ChatbotApp: App {
13-
@State private var viewModel = ChatbotViewModel()
13+
@SwiftCrossUI.State private var viewModel = ChatbotViewModel()
1414

1515
var body: some Scene {
1616
WindowGroup("ChatBot") {
1717
#hotReloadable {
18-
ZStack {
19-
// Main content with sidebar
20-
HStack(spacing: 0) {
21-
// Thread Sidebar - conditionally shown
22-
if viewModel.showSidebar {
23-
ThreadSidebarView(
24-
threads: Binding(
25-
get: { viewModel.threads },
26-
set: { viewModel.threads = $0 }
27-
),
28-
selectedThread: Binding(
29-
get: { viewModel.selectedThread },
30-
set: { viewModel.selectedThread = $0 }
31-
),
32-
showSidebar: Binding(
33-
get: { viewModel.showSidebar },
34-
set: { viewModel.showSidebar = $0 }
35-
),
36-
onNewThread: viewModel.createNewThread,
37-
onSelectThread: viewModel.selectThread,
38-
onDeleteThread: viewModel.deleteThread
39-
)
40-
.frame(width: 300)
41-
}
42-
43-
// Main chat area
44-
MainChatView(viewModel: viewModel)
45-
}
46-
.frame(maxWidth: .infinity, maxHeight: .infinity)
47-
18+
NavigationSplitView {
19+
// Sidebar content
20+
ThreadSidebarView(
21+
threads: viewModel.threadsBinding,
22+
selectedThread: viewModel.selectedThreadBinding,
23+
onNewThread: viewModel.createNewThread,
24+
onSelectThread: viewModel.selectThread,
25+
onDeleteThread: viewModel.deleteThread
26+
)
27+
} detail: {
28+
// Main chat area
29+
MainChatView(viewModel: viewModel)
30+
}
31+
.overlay {
4832
// Settings Overlay
4933
if viewModel.showSettings {
5034
ChatSettingsDialog(
51-
isPresented: Binding(
52-
get: { viewModel.showSettings },
53-
set: { viewModel.showSettings = $0 }
54-
),
55-
selectedModel: Binding(
56-
get: { viewModel.selectedLLM },
57-
set: { viewModel.selectedLLM = $0 }
58-
),
35+
isPresented: viewModel.showSettingsBinding,
36+
selectedModel: viewModel.selectedLLMBinding,
5937
openAIService: viewModel.openAIService,
6038
apiKeyStorage: viewModel.apiKeyStorage,
6139
onSave: viewModel.reloadAPIKey

Examples/Sources/ChatbotExample/Services/OpenAIService.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import OpenAI
44

55
// MARK: - OpenAI Service
66

7-
class OpenAIService: SwiftCrossUI.ObservableObject {
7+
class OpenAIService {
88
private var openAI: OpenAI?
99

1010
func configure(apiKey: String) {

Examples/Sources/ChatbotExample/Services/ThreadStorage.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import SwiftCrossUI
33

44
// MARK: - Thread Storage Service
55

6-
class ThreadStorage: SwiftCrossUI.ObservableObject {
6+
class ThreadStorage {
77
private let threadsKey = "chatThreads"
88
private let messagesKey = "threadMessages"
99

Examples/Sources/ChatbotExample/ViewModels/ChatbotViewModel.swift

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ class ChatbotViewModel: SwiftCrossUI.ObservableObject {
99
// MARK: - Published Properties
1010
@SwiftCrossUI.Published var selectedThread: ChatThread?
1111
@SwiftCrossUI.Published var threads: [ChatThread] = []
12-
@SwiftCrossUI.Published var showSidebar = true
1312
@SwiftCrossUI.Published var currentMessage = ""
1413
@SwiftCrossUI.Published var selectedLLM: LLM = .gpt3_5Turbo
1514
@SwiftCrossUI.Published var isLoading = false
@@ -156,10 +155,6 @@ class ChatbotViewModel: SwiftCrossUI.ObservableObject {
156155

157156
// MARK: - UI State Management
158157

159-
func toggleSidebar() {
160-
showSidebar.toggle()
161-
}
162-
163158
func toggleSettings() {
164159
showSettings.toggle()
165160
}
@@ -194,3 +189,49 @@ class ChatbotViewModel: SwiftCrossUI.ObservableObject {
194189
}
195190
}
196191
}
192+
193+
// MARK: - Binding Extensions
194+
195+
extension ChatbotViewModel {
196+
var threadsBinding: Binding<[ChatThread]> {
197+
Binding(
198+
get: { self.threads },
199+
set: { self.threads = $0 }
200+
)
201+
}
202+
203+
var selectedThreadBinding: Binding<ChatThread?> {
204+
Binding(
205+
get: { self.selectedThread },
206+
set: { self.selectedThread = $0 }
207+
)
208+
}
209+
210+
var currentMessageBinding: Binding<String> {
211+
Binding(
212+
get: { self.currentMessage },
213+
set: { self.currentMessage = $0 }
214+
)
215+
}
216+
217+
var errorMessageBinding: Binding<String?> {
218+
Binding(
219+
get: { self.errorMessage },
220+
set: { self.errorMessage = $0 }
221+
)
222+
}
223+
224+
var showSettingsBinding: Binding<Bool> {
225+
Binding(
226+
get: { self.showSettings },
227+
set: { self.showSettings = $0 }
228+
)
229+
}
230+
231+
var selectedLLMBinding: Binding<LLM> {
232+
Binding(
233+
get: { self.selectedLLM },
234+
set: { self.selectedLLM = $0 }
235+
)
236+
}
237+
}

Examples/Sources/ChatbotExample/Views/ChatSettingsDialog.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ struct ModelInfo: Identifiable, Equatable {
1919
struct ChatSettingsDialog: View {
2020
@Binding var isPresented: Bool
2121
@Binding var selectedModel: LLM
22-
@State private var model: ChatSettingsViewModel
22+
@SwiftCrossUI.State private var model: ChatSettingsViewModel
2323

2424
let onSave: () -> Void
2525

Examples/Sources/ChatbotExample/Views/LLMSelectionView.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ extension Array {
1515

1616
struct LLMSelectionView: View {
1717
@Binding var selectedModel: LLM
18-
@State private var availableModels: [LLM] = [.gpt4_o, .gpt4_o_mini, .gpt4_turbo, .gpt4, .gpt3_5Turbo]
19-
@State private var isLoading = false
20-
@State private var errorMessage: String?
18+
@SwiftCrossUI.State private var availableModels: [LLM] = [.gpt4_o, .gpt4_o_mini, .gpt4_turbo, .gpt4, .gpt3_5Turbo]
19+
@SwiftCrossUI.State private var isLoading = false
20+
@SwiftCrossUI.State private var errorMessage: String?
2121

2222
let openAIService: OpenAIService
2323

Examples/Sources/ChatbotExample/Views/MainChatView.swift

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,8 @@ struct MainChatView: View {
3030
// Input area
3131
if viewModel.isThreadSelected {
3232
ChatInputView(
33-
currentMessage: Binding(
34-
get: { viewModel.currentMessage },
35-
set: { viewModel.currentMessage = $0 }
36-
),
37-
errorMessage: Binding(
38-
get: { viewModel.errorMessage },
39-
set: { viewModel.errorMessage = $0 }
40-
),
33+
currentMessage: viewModel.currentMessageBinding,
34+
errorMessage: viewModel.errorMessageBinding,
4135
isLoading: viewModel.isLoading,
4236
messageCount: viewModel.currentThreadMessages.count,
4337
onSend: viewModel.sendMessage
@@ -54,14 +48,6 @@ struct ChatHeaderView: View {
5448

5549
var body: some View {
5650
HStack {
57-
// Sidebar toggle button (when hidden)
58-
if !viewModel.showSidebar {
59-
Button("") {
60-
viewModel.toggleSidebar()
61-
}
62-
.iconButtonLargeStyle()
63-
}
64-
6551
// Thread title or placeholder
6652
VStack(alignment: .leading, spacing: AppSpacing.xs) {
6753
if let thread = viewModel.selectedThread {

Examples/Sources/ChatbotExample/Views/ThreadSidebarView.swift

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import Foundation
66
struct ThreadSidebarView: View {
77
@Binding var threads: [ChatThread]
88
@Binding var selectedThread: ChatThread?
9-
@Binding var showSidebar: Bool
109

1110
let onNewThread: () -> Void
1211
let onSelectThread: (ChatThread) -> Void
@@ -23,11 +22,6 @@ struct ThreadSidebarView: View {
2322
.fixedSize(horizontal: true, vertical: false)
2423

2524
Spacer()
26-
27-
Button("×") {
28-
showSidebar = false
29-
}
30-
.iconButtonLargeStyle()
3125
}
3226
.padding(.horizontal, AppSpacing.xl)
3327
.padding(.vertical, AppSpacing.sm)
@@ -71,7 +65,6 @@ struct ThreadSidebarView: View {
7165
}
7266
.frame(maxHeight: .infinity)
7367
.background(AppColors.surface)
74-
.frame(width: 300)
7568
}
7669
}
7770

0 commit comments

Comments
 (0)