Skip to content

Commit f0e4b88

Browse files
committed
Get open chat command handler from service
1 parent 33a785c commit f0e4b88

7 files changed

Lines changed: 128 additions & 22 deletions

File tree

Core/Sources/HostApp/FeatureSettings/Chat/ChatSettingsGeneralSectionView.swift

Lines changed: 62 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
import Client
12
import Preferences
23
import SharedUIComponents
34
import SwiftUI
5+
import XPCShared
46

57
#if canImport(ProHostApp)
68
import ProHostApp
@@ -33,7 +35,51 @@ struct ChatSettingsGeneralSectionView: View {
3335
@AppStorage(\.openChatInBrowserURL) var openChatInBrowserURL
3436
@AppStorage(\.openChatInBrowserInInAppBrowser) var openChatInBrowserInInAppBrowser
3537

36-
init() {}
38+
var refreshExtensionExtensionOpenChatHandlerTask: Task<Void, Never>?
39+
40+
@MainActor
41+
@Published
42+
var openChatOptions = [OpenChatMode]()
43+
44+
init() {
45+
Task { @MainActor in
46+
refreshExtensionOpenChatHandlers()
47+
}
48+
refreshExtensionExtensionOpenChatHandlerTask = Task { [weak self] in
49+
let sequence = NotificationCenter.default
50+
.notifications(named: NSApplication.didBecomeActiveNotification)
51+
for await _ in sequence {
52+
guard let self else { return }
53+
await MainActor.run {
54+
self.refreshExtensionOpenChatHandlers()
55+
}
56+
}
57+
}
58+
}
59+
60+
@MainActor
61+
func refreshExtensionOpenChatHandlers() {
62+
guard let service = try? getService() else { return }
63+
Task { @MainActor in
64+
let handlers = try await service
65+
.send(requestBody: ExtensionServiceRequests.GetExtensionOpenChatHandlers())
66+
openChatOptions = handlers.map {
67+
if $0.isBuiltIn {
68+
return .builtinExtension(
69+
extensionIdentifier: $0.bundleIdentifier,
70+
id: $0.id,
71+
tabName: $0.tabName
72+
)
73+
} else {
74+
return .externalExtension(
75+
extensionIdentifier: $0.bundleIdentifier,
76+
id: $0.id,
77+
tabName: $0.tabName
78+
)
79+
}
80+
}
81+
}
82+
}
3783
}
3884

3985
@Environment(\.openURL) var openURL
@@ -58,21 +104,27 @@ struct ChatSettingsGeneralSectionView: View {
58104
Form {
59105
Picker(
60106
"Open Chat Mode",
61-
selection: $settings.openChatMode
107+
selection: .init(get: {
108+
settings.openChatMode.value
109+
}, set: {
110+
settings.openChatMode = .init($0)
111+
})
62112
) {
63-
ForEach(OpenChatMode.allCases, id: \.rawValue) { mode in
113+
Text("Open chat panel").tag(OpenChatMode.chatPanel)
114+
Text("Open web page in browser").tag(OpenChatMode.browser)
115+
ForEach(settings.openChatOptions) { mode in
64116
switch mode {
65-
case .chatPanel:
66-
Text("Open chat panel").tag(mode)
67-
case .browser:
68-
Text("Open web page in browser").tag(mode)
69-
case .codeiumChat:
70-
Text("Open Codeium chat tab").tag(mode)
117+
case let .builtinExtension(_, _, name):
118+
Text("Open \(name) tab").tag(mode)
119+
case let .externalExtension(_, _, name):
120+
Text("Open \(name) tab").tag(mode)
121+
default:
122+
EmptyView()
71123
}
72124
}
73125
}
74126

75-
if settings.openChatMode == .browser {
127+
if settings.openChatMode.value == .browser {
76128
TextField(
77129
"Chat web page URL",
78130
text: $settings.openChatInBrowserURL,

Core/Sources/HostApp/FeatureSettings/Suggestion/SuggestionSettingsGeneralSectionView.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,6 @@ struct SuggestionSettingsGeneralSectionView: View {
8888
extensionSuggestionFeatureProviderOptions = services.map {
8989
.init(name: $0.name, bundleIdentifier: $0.bundleIdentifier)
9090
}
91-
print(services.map(\.bundleIdentifier))
92-
print(suggestionFeatureProvider)
9391
}
9492
}
9593
}

Core/Sources/Service/Service.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,26 @@ public extension Service {
138138
reply: reply
139139
)
140140
#endif
141+
142+
try ExtensionServiceRequests.GetExtensionOpenChatHandlers.handle(
143+
endpoint: endpoint,
144+
requestBody: requestBody,
145+
reply: reply
146+
) { _ in
147+
BuiltinExtensionManager.shared.extensions.reduce(into: []) { result, ext in
148+
let tabs = ext.chatTabTypes
149+
for tab in tabs {
150+
if tab.canHandleOpenChatCommand {
151+
result.append(.init(
152+
bundleIdentifier: ext.extensionIdentifier,
153+
id: tab.name,
154+
tabName: tab.name,
155+
isBuiltIn: true
156+
))
157+
}
158+
}
159+
}
160+
}
141161
} catch is XPCRequestHandlerHitError {
142162
return
143163
} catch {

Core/Sources/Service/SuggestionCommandHandler/PseudoCommandHandler.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -414,16 +414,16 @@ struct PseudoCommandHandler: CommandHandler {
414414
await openURL(url)
415415
}
416416
}
417-
case let .builtinExtension(extensionIdentifier, tabName):
417+
case let .builtinExtension(extensionIdentifier, id, _):
418418
guard let ext = BuiltinExtensionManager.shared.extensions
419419
.first(where: { $0.extensionIdentifier == extensionIdentifier }),
420-
let tab = ext.chatTabTypes.first(where: { $0.name == tabName })
420+
let tab = ext.chatTabTypes.first(where: { $0.name == id })
421421
else { return }
422422
Task { @MainActor in
423423
let store = Service.shared.guiController.store
424424
await store.send(
425425
.createAndSwitchToChatTabIfNeededMatching(
426-
check: { $0.name == tabName },
426+
check: { $0.name == id },
427427
kind: .init(tab.defaultChatBuilder())
428428
)
429429
).finish()
@@ -432,17 +432,17 @@ struct PseudoCommandHandler: CommandHandler {
432432
activateThisApp: activateThisApp
433433
))
434434
}
435-
case let .externalExtension(extensionIdentifier, tabName):
435+
case let .externalExtension(extensionIdentifier, id, _):
436436
guard let ext = BuiltinExtensionManager.shared.extensions
437437
.first(where: { $0.extensionIdentifier == "plus" }),
438438
let tab = ext.chatTabTypes
439-
.first(where: { $0.name == "\(extensionIdentifier).\(tabName)" })
439+
.first(where: { $0.name == "\(extensionIdentifier).\(id)" })
440440
else { return }
441441
Task { @MainActor in
442442
let store = Service.shared.guiController.store
443443
await store.send(
444444
.createAndSwitchToChatTabIfNeededMatching(
445-
check: { $0.name == "\(extensionIdentifier).\(tabName)" },
445+
check: { $0.name == "\(extensionIdentifier).\(id)" },
446446
kind: .init(tab.defaultChatBuilder())
447447
)
448448
).finish()
Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,28 @@
11
import Foundation
22

3-
public enum OpenChatMode: Codable, Equatable {
3+
public enum OpenChatMode: Codable, Equatable, Identifiable, Hashable {
4+
public var id: String {
5+
switch self {
6+
case .chatPanel:
7+
return "chatPanel"
8+
case .browser:
9+
return "browser"
10+
case let .builtinExtension(extensionIdentifier, id, _):
11+
return "builtinExtension-\(extensionIdentifier)-\(id)"
12+
case let .externalExtension(extensionIdentifier, id, _):
13+
return "externalExtension-\(extensionIdentifier)-\(id)"
14+
}
15+
}
16+
417
public enum LegacyOpenChatMode: String {
518
case chatPanel
619
case browser
720
case codeiumChat
821
}
9-
22+
1023
case chatPanel
1124
case browser
12-
case builtinExtension(extensionIdentifier: String, tabName: String)
13-
case externalExtension(extensionIdentifier: String, tabName: String)
25+
case builtinExtension(extensionIdentifier: String, id: String, tabName: String)
26+
case externalExtension(extensionIdentifier: String, id: String, tabName: String)
1427
}
28+

Tool/Sources/Preferences/UserDefaults.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ public extension UserDefaults {
6060
case .codeiumChat:
6161
return .init(.builtinExtension(
6262
extensionIdentifier: "com.codeium",
63+
id: "Codeium Chat",
6364
tabName: "Codeium Chat"
6465
))
6566
}

Tool/Sources/XPCShared/XPCServiceProtocol.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,27 @@ public enum ExtensionServiceRequests {
9292

9393
public init() {}
9494
}
95+
96+
public struct GetExtensionOpenChatHandlers: ExtensionServiceRequestType {
97+
public struct HandlerInfo: Codable {
98+
public var bundleIdentifier: String
99+
public var id: String
100+
public var tabName: String
101+
public var isBuiltIn: Bool
102+
103+
public init(bundleIdentifier: String, id: String, tabName: String, isBuiltIn: Bool) {
104+
self.bundleIdentifier = bundleIdentifier
105+
self.id = id
106+
self.tabName = tabName
107+
self.isBuiltIn = isBuiltIn
108+
}
109+
}
110+
111+
public typealias ResponseBody = [HandlerInfo]
112+
public static let endpoint = "GetExtensionOpenChatHandlers"
113+
114+
public init() {}
115+
}
95116
}
96117

97118
public struct XPCRequestHandlerHitError: Error, LocalizedError {

0 commit comments

Comments
 (0)