Skip to content

Commit dcc56b4

Browse files
committed
Split chat tab item and menu
1 parent 45581f8 commit dcc56b4

File tree

5 files changed

+63
-89
lines changed

5 files changed

+63
-89
lines changed

Core/Sources/ChatGPTChatTab/ChatContextMenu.swift

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,19 @@ import AppKit
22
import SharedUIComponents
33
import SwiftUI
44

5+
struct ChatTabItemView: View {
6+
@ObservedObject var chat: ChatProvider
7+
8+
var body: some View {
9+
Text(chat.title)
10+
}
11+
}
12+
513
struct ChatContextMenu: View {
614
@ObservedObject var chat: ChatProvider
715
@AppStorage(\.customCommands) var customCommands
816

917
var body: some View {
10-
Text(chat.title)
11-
.contextMenu {
12-
menu
13-
}
14-
}
15-
16-
@ViewBuilder
17-
var menu: some View {
1818
currentSystemPrompt
1919
currentExtraSystemPrompt
2020
resetPrompt

Core/Sources/ChatGPTChatTab/ChatGPTChatTab.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ public class ChatGPTChatTab: ChatTab {
4242
}
4343

4444
public func buildTabItem() -> any View {
45+
ChatTabItemView(chat: provider)
46+
}
47+
48+
public func buildMenu() -> any View {
4549
ChatContextMenu(chat: provider)
4650
}
4751

Core/Sources/SuggestionWidget/ChatWindowView.swift

Lines changed: 26 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,9 @@ struct ChatTabBar: View {
182182
content: { tab.tabItem },
183183
isSelected: info.id == viewStore.state.selectedTabId
184184
)
185+
.contextMenu {
186+
tab.menu
187+
}
185188
.id(info.id)
186189
} else {
187190
EmptyView()
@@ -359,62 +362,8 @@ struct CreateOtherChatTabMenuStyle: MenuStyle {
359362
}
360363
}
361364

362-
class FakeChatTab: ChatTab {
363-
static var name: String { "Fake" }
364-
static func chatBuilders(externalDependency: Void) -> [ChatTabBuilder] { [Builder()] }
365-
366-
struct Builder: ChatTabBuilder {
367-
var title: String = "Title"
368-
369-
func build(store: StoreOf<ChatTabItem>) async -> (any ChatTab)? {
370-
return FakeChatTab(store: store)
371-
}
372-
}
373-
374-
func buildTabItem() -> any View {
375-
Text("Fake")
376-
.contextMenu {
377-
Text("Menu Item")
378-
Text("Menu Item")
379-
}
380-
}
381-
382-
func buildView() -> any View {
383-
ChatPanel(
384-
chat: .init(
385-
history: [
386-
.init(id: "1", role: .assistant, text: "Hello World"),
387-
],
388-
isReceivingMessage: false
389-
),
390-
typedMessage: "Hello World!"
391-
)
392-
}
393-
394-
func restorableState() async -> Data {
395-
return Data()
396-
}
397-
398-
static func restore(
399-
from data: Data,
400-
externalDependency: ()
401-
) async throws -> any ChatTabBuilder {
402-
return Builder()
403-
}
404-
405-
convenience init(id: String, title: String) {
406-
self.init(store: .init(
407-
initialState: .init(id: id, title: title),
408-
reducer: ChatTabItem()
409-
))
410-
}
411-
412-
func start() {}
413-
}
414-
415365
struct ChatWindowView_Previews: PreviewProvider {
416366
static let pool = ChatTabPool([
417-
"1": FakeChatTab(id: "1", title: "Hello I am a chatbot"),
418367
"2": EmptyChatTab(id: "2"),
419368
"3": EmptyChatTab(id: "3"),
420369
"4": EmptyChatTab(id: "4"),
@@ -423,30 +372,31 @@ struct ChatWindowView_Previews: PreviewProvider {
423372
"7": EmptyChatTab(id: "7"),
424373
])
425374

426-
static var previews: some View {
427-
ChatWindowView(
428-
store: .init(
429-
initialState: .init(
430-
chatTabGroup: .init(
431-
tabInfo: [
432-
.init(id: "1", title: "Fake"),
433-
.init(id: "2", title: "Empty-2"),
434-
.init(id: "3", title: "Empty-3"),
435-
.init(id: "4", title: "Empty-4"),
436-
.init(id: "5", title: "Empty-5"),
437-
.init(id: "6", title: "Empty-6"),
438-
.init(id: "7", title: "Empty-7"),
439-
],
440-
selectedTabId: "1"
441-
),
442-
isPanelDisplayed: true
375+
static func createStore() -> StoreOf<ChatPanelFeature> {
376+
StoreOf<ChatPanelFeature>(
377+
initialState: .init(
378+
chatTabGroup: .init(
379+
tabInfo: [
380+
.init(id: "2", title: "Empty-2"),
381+
.init(id: "3", title: "Empty-3"),
382+
.init(id: "4", title: "Empty-4"),
383+
.init(id: "5", title: "Empty-5"),
384+
.init(id: "6", title: "Empty-6"),
385+
.init(id: "7", title: "Empty-7"),
386+
],
387+
selectedTabId: "2"
443388
),
444-
reducer: ChatPanelFeature()
445-
)
389+
isPanelDisplayed: true
390+
),
391+
reducer: ChatPanelFeature()
446392
)
447-
.xcodeStyleFrame()
448-
.padding()
449-
.environment(\.chatTabPool, pool)
393+
}
394+
395+
static var previews: some View {
396+
ChatWindowView(store: createStore())
397+
.xcodeStyleFrame()
398+
.padding()
399+
.environment(\.chatTabPool, pool)
450400
}
451401
}
452402

Core/Sources/SuggestionWidget/ModuleDependency.swift

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,7 @@ struct ActiveApplicationMonitorKey: DependencyKey {
7575
}
7676

7777
struct ChatTabBuilderCollectionKey: DependencyKey {
78-
static let liveValue: () -> [ChatTabBuilderCollection] = {
79-
[.folder(title: "A", kinds: FakeChatTab.chatBuilders().map(ChatTabKind.init))]
80-
}
78+
static let liveValue: () -> [ChatTabBuilderCollection] = { [] }
8179
}
8280

8381
struct ActivatePreviouslyActiveXcodeKey: DependencyKey {
@@ -135,3 +133,4 @@ extension DependencyValues {
135133
set { self[ActivateExtensionServiceKey.self] = newValue }
136134
}
137135
}
136+

Tool/Sources/ChatTab/ChatTab.swift

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,12 @@ public protocol ChatTabType {
2323
/// Build the view for this chat tab.
2424
@ViewBuilder
2525
func buildView() -> any View
26-
/// Build the menu for this chat tab.
26+
/// Build the tabItem for this chat tab.
2727
@ViewBuilder
2828
func buildTabItem() -> any View
29+
/// Build the menu for this chat tab.
30+
@ViewBuilder
31+
func buildMenu() -> any View
2932
/// The name of this chat tab type.
3033
static var name: String { get }
3134
/// Available builders for this chat tab.
@@ -82,7 +85,7 @@ open class BaseChatTab {
8285
}
8386
}
8487

85-
/// The menu for this chat tab.
88+
/// The tab item for this chat tab.
8689
@ViewBuilder
8790
public var tabItem: some View {
8891
let id = "ChatTabMenu\(id)"
@@ -95,6 +98,20 @@ open class BaseChatTab {
9598
EmptyView().id(id)
9699
}
97100
}
101+
102+
/// The tab item for this chat tab.
103+
@ViewBuilder
104+
public var menu: some View {
105+
let id = "ChatTabMenu\(id)"
106+
if let tab = self as? (any ChatTabType) {
107+
ContentView(buildView: tab.buildMenu).id(id)
108+
.onAppear {
109+
Task { @MainActor in self.startIfNotStarted() }
110+
}
111+
} else {
112+
EmptyView().id(id)
113+
}
114+
}
98115

99116
@MainActor
100117
func startIfNotStarted() {
@@ -165,6 +182,10 @@ public class EmptyChatTab: ChatTab {
165182
public func buildTabItem() -> any View {
166183
Text("Empty-\(id)")
167184
}
185+
186+
public func buildMenu() -> any View {
187+
Text("Empty-\(id)")
188+
}
168189

169190
public func restorableState() async -> Data {
170191
return Data()

0 commit comments

Comments
 (0)