Skip to content

Commit 8848280

Browse files
committed
Merge branch 'feature/migrate-to-composible-architecture' into develop
2 parents 449c9db + be51d40 commit 8848280

38 files changed

Lines changed: 2024 additions & 1108 deletions

Copilot for Xcode.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved

Lines changed: 63 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Core/Package.swift

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ let package = Package(
5151
.package(url: "https://github.com/kishikawakatsumi/KeychainAccess", from: "4.2.2"),
5252
.package(url: "https://github.com/pvieito/PythonKit.git", branch: "master"),
5353
.package(url: "https://github.com/pointfreeco/swift-parsing", from: "0.12.1"),
54+
.package(
55+
url: "https://github.com/pointfreeco/swift-composable-architecture",
56+
from: "0.55.0"
57+
),
5458
],
5559
targets: [
5660
// MARK: - Main
@@ -83,6 +87,7 @@ let package = Package(
8387
"PromptToCodeService",
8488
"ServiceUpdateMigration",
8589
"UserDefaultsObserver",
90+
"ChatTab",
8691
.product(name: "Logger", package: "Tool"),
8792
.product(name: "PythonHelper", package: "Tool"),
8893
.product(name: "OpenAIService", package: "Tool"),
@@ -185,10 +190,10 @@ let package = Package(
185190
"MathChatPlugin",
186191
"SearchChatPlugin",
187192
"ShortcutChatPlugin",
188-
193+
189194
// context collectors
190195
"WebChatContextCollector",
191-
196+
192197
.product(name: "Parsing", package: "swift-parsing"),
193198
.product(name: "OpenAIService", package: "Tool"),
194199
.product(name: "Preferences", package: "Tool"),
@@ -215,21 +220,41 @@ let package = Package(
215220
]
216221
),
217222

223+
.target(
224+
name: "ChatTab",
225+
dependencies: [
226+
"SharedUIComponents",
227+
.product(name: "OpenAIService", package: "Tool"),
228+
.product(name: "Logger", package: "Tool"),
229+
.product(name: "MarkdownUI", package: "swift-markdown-ui"),
230+
]
231+
),
232+
218233
// MARK: - UI
219234

235+
.target(
236+
name: "SharedUIComponents",
237+
dependencies: [
238+
"Highlightr",
239+
"Splash",
240+
.product(name: "Preferences", package: "Tool"),
241+
]
242+
),
243+
220244
.target(
221245
name: "SuggestionWidget",
222246
dependencies: [
247+
"ChatTab",
223248
"ActiveApplicationMonitor",
224249
"AXNotificationStream",
225250
"Environment",
226-
"Highlightr",
227-
"Splash",
228251
"UserDefaultsObserver",
229252
"XcodeInspector",
253+
"SharedUIComponents",
230254
.product(name: "Logger", package: "Tool"),
231255
.product(name: "AsyncAlgorithms", package: "swift-async-algorithms"),
232256
.product(name: "MarkdownUI", package: "swift-markdown-ui"),
257+
.product(name: "ComposableArchitecture", package: "swift-composable-architecture"),
233258
]
234259
),
235260
.testTarget(name: "SuggestionWidgetTests", dependencies: ["SuggestionWidget"]),
@@ -335,9 +360,9 @@ let package = Package(
335360
],
336361
path: "Sources/ChatPlugins/ShortcutChatPlugin"
337362
),
338-
363+
339364
// MAKR: - Chat Context Collector
340-
365+
341366
.target(
342367
name: "WebChatContextCollector",
343368
dependencies: [
@@ -348,7 +373,7 @@ let package = Package(
348373
.product(name: "Preferences", package: "Tool"),
349374
],
350375
path: "Sources/ChatContextCollectors/WebChatContextCollector"
351-
)
376+
),
352377
]
353378
)
354379

Core/Sources/SuggestionWidget/SuggestionPanelContent/ChatPanel.swift renamed to Core/Sources/ChatTab/ChatGPT/ChatPanel.swift

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,21 @@
11
import AppKit
22
import MarkdownUI
3+
import SharedUIComponents
34
import SwiftUI
45

56
private let r: Double = 8
67

7-
struct ChatPanel: View {
8+
public struct ChatPanel: View {
89
let chat: ChatProvider
910
@Namespace var inputAreaNamespace
1011
@State var typedMessage = ""
12+
13+
public init(chat: ChatProvider, typedMessage: String = "") {
14+
self.chat = chat
15+
self.typedMessage = typedMessage
16+
}
1117

12-
var body: some View {
18+
public var body: some View {
1319
VStack(spacing: 0) {
1420
ChatPanelToolbar(chat: chat)
1521
Divider()
@@ -23,7 +29,6 @@ struct ChatPanel: View {
2329
)
2430
}
2531
.background(.regularMaterial)
26-
.xcodeStyleFrame()
2732
}
2833
}
2934

Core/Sources/SuggestionWidget/ChatProvider.swift renamed to Core/Sources/ChatTab/ChatGPT/ChatProvider.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import SwiftUI
55

66
public final class ChatProvider: ObservableObject {
77
public typealias MessageID = String
8-
let id = UUID()
8+
public let id = UUID()
99
@Published public var history: [ChatMessage] = []
1010
@Published public var isReceivingMessage = false
1111
public var pluginIdentifiers: [String] = []
@@ -74,7 +74,7 @@ public struct ChatMessage: Equatable {
7474
case function
7575
case ignored
7676
}
77-
77+
7878
public var id: String
7979
public var role: Role
8080
public var text: String
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
import AppKit
2+
import MarkdownUI
3+
import SharedUIComponents
4+
import SwiftUI
5+
6+
extension Color {
7+
static var contentBackground: Color {
8+
Color(nsColor: NSColor(name: nil, dynamicProvider: { appearance in
9+
if appearance.isDarkMode {
10+
return #colorLiteral(red: 0.1580096483, green: 0.1730263829, blue: 0.2026666105, alpha: 1)
11+
}
12+
return .white
13+
}))
14+
}
15+
16+
static var userChatContentBackground: Color {
17+
Color(nsColor: NSColor(name: nil, dynamicProvider: { appearance in
18+
if appearance.isDarkMode {
19+
return #colorLiteral(red: 0.2284317913, green: 0.2145925438, blue: 0.3214019983, alpha: 1)
20+
}
21+
return #colorLiteral(red: 0.896820749, green: 0.8709097223, blue: 0.9766687925, alpha: 1)
22+
}))
23+
}
24+
}
25+
26+
extension NSAppearance {
27+
var isDarkMode: Bool {
28+
if bestMatch(from: [.darkAqua, .aqua]) == .darkAqua {
29+
return true
30+
} else {
31+
return false
32+
}
33+
}
34+
}
35+
36+
extension MarkdownUI.Theme {
37+
static func custom(fontSize: Double) -> MarkdownUI.Theme {
38+
.gitHub.text {
39+
ForegroundColor(.primary)
40+
BackgroundColor(Color.clear)
41+
FontSize(fontSize)
42+
}
43+
.codeBlock { configuration in
44+
configuration.label
45+
.relativeLineSpacing(.em(0.225))
46+
.markdownTextStyle {
47+
FontFamilyVariant(.monospaced)
48+
FontSize(.em(0.85))
49+
}
50+
.padding(16)
51+
.padding(.top, 14)
52+
.background(Color(nsColor: .textBackgroundColor).opacity(0.7))
53+
.clipShape(RoundedRectangle(cornerRadius: 6))
54+
.overlay(alignment: .top) {
55+
HStack(alignment: .center) {
56+
Text(configuration.language ?? "code")
57+
.foregroundStyle(.tertiary)
58+
.font(.callout)
59+
.padding(.leading, 8)
60+
.lineLimit(1)
61+
Spacer()
62+
CopyButton {
63+
NSPasteboard.general.clearContents()
64+
NSPasteboard.general.setString(configuration.content, forType: .string)
65+
}
66+
}
67+
}
68+
.markdownMargin(top: 4, bottom: 16)
69+
}
70+
}
71+
72+
static func functionCall(fontSize: Double) -> MarkdownUI.Theme {
73+
.gitHub.text {
74+
ForegroundColor(.secondary)
75+
BackgroundColor(Color.clear)
76+
FontSize(fontSize - 1)
77+
}
78+
.list { configuration in
79+
configuration.label
80+
.markdownMargin(top: 4, bottom: 4)
81+
}
82+
.paragraph { configuration in
83+
configuration.label
84+
.markdownMargin(top: 0, bottom: 4)
85+
}
86+
.codeBlock { configuration in
87+
configuration.label
88+
.relativeLineSpacing(.em(0.225))
89+
.markdownTextStyle {
90+
FontFamilyVariant(.monospaced)
91+
FontSize(.em(0.85))
92+
}
93+
.padding(16)
94+
.background(Color(nsColor: .textBackgroundColor).opacity(0.7))
95+
.clipShape(RoundedRectangle(cornerRadius: 6))
96+
.markdownMargin(top: 4, bottom: 4)
97+
}
98+
}
99+
}
100+

Core/Sources/ChatTab/ChatTab.swift

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import Foundation
2+
import SwiftUI
3+
4+
public protocol ChatTab {
5+
associatedtype Body: View
6+
var id: UUID { get }
7+
@ViewBuilder @MainActor var body: Body { get }
8+
}
9+
10+
public class ChatGPTChatTab: ChatTab {
11+
public var provider: ChatProvider
12+
public var id: UUID { provider.id }
13+
public var body: some View {
14+
ChatPanel(chat: provider)
15+
}
16+
17+
public init(provider: ChatProvider) {
18+
self.provider = provider
19+
}
20+
}
21+
22+
public class EmptyChatTab: ChatTab {
23+
public var id: UUID { .init() }
24+
25+
public var body: some View {
26+
EmptyView()
27+
}
28+
}

Core/Sources/Service/GUI/ChatProvider+Service.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import ChatService
2+
import ChatTab
23
import Combine
34
import Foundation
45
import OpenAIService
@@ -96,14 +97,14 @@ extension ChatProvider {
9697
await service.resetPrompt()
9798
}
9899
}
99-
100+
100101
onRunCustomCommand = { command in
101102
Task {
102103
let commandHandler = PseudoCommandHandler()
103104
await commandHandler.handleCustomCommand(command)
104105
}
105106
}
106-
107+
107108
onSetAsExtraPrompt = { id in
108109
Task {
109110
await service.setMessageAsExtraPrompt(id: id)

0 commit comments

Comments
 (0)