Skip to content

Commit 9e1dd6f

Browse files
committed
Adjust file location
1 parent 449c9db commit 9e1dd6f

17 files changed

+241
-55
lines changed

Core/Package.swift

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ let package = Package(
8383
"PromptToCodeService",
8484
"ServiceUpdateMigration",
8585
"UserDefaultsObserver",
86+
"ChatTab",
8687
.product(name: "Logger", package: "Tool"),
8788
.product(name: "PythonHelper", package: "Tool"),
8889
.product(name: "OpenAIService", package: "Tool"),
@@ -185,10 +186,10 @@ let package = Package(
185186
"MathChatPlugin",
186187
"SearchChatPlugin",
187188
"ShortcutChatPlugin",
188-
189+
189190
// context collectors
190191
"WebChatContextCollector",
191-
192+
192193
.product(name: "Parsing", package: "swift-parsing"),
193194
.product(name: "OpenAIService", package: "Tool"),
194195
.product(name: "Preferences", package: "Tool"),
@@ -215,18 +216,36 @@ let package = Package(
215216
]
216217
),
217218

219+
.target(
220+
name: "ChatTab",
221+
dependencies: [
222+
"SharedUIComponents",
223+
.product(name: "Logger", package: "Tool"),
224+
.product(name: "MarkdownUI", package: "swift-markdown-ui"),
225+
]
226+
),
227+
218228
// MARK: - UI
219229

230+
.target(
231+
name: "SharedUIComponents",
232+
dependencies: [
233+
"Highlightr",
234+
"Splash",
235+
.product(name: "Preferences", package: "Tool"),
236+
]
237+
),
238+
220239
.target(
221240
name: "SuggestionWidget",
222241
dependencies: [
242+
"ChatTab",
223243
"ActiveApplicationMonitor",
224244
"AXNotificationStream",
225245
"Environment",
226-
"Highlightr",
227-
"Splash",
228246
"UserDefaultsObserver",
229247
"XcodeInspector",
248+
"SharedUIComponents",
230249
.product(name: "Logger", package: "Tool"),
231250
.product(name: "AsyncAlgorithms", package: "swift-async-algorithms"),
232251
.product(name: "MarkdownUI", package: "swift-markdown-ui"),
@@ -335,9 +354,9 @@ let package = Package(
335354
],
336355
path: "Sources/ChatPlugins/ShortcutChatPlugin"
337356
),
338-
357+
339358
// MAKR: - Chat Context Collector
340-
359+
341360
.target(
342361
name: "WebChatContextCollector",
343362
dependencies: [
@@ -348,7 +367,7 @@ let package = Package(
348367
.product(name: "Preferences", package: "Tool"),
349368
],
350369
path: "Sources/ChatContextCollectors/WebChatContextCollector"
351-
)
370+
),
352371
]
353372
)
354373

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)

Core/Sources/Service/GUI/WidgetDataSource.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import ActiveApplicationMonitor
22
import ChatService
3+
import ChatTab
34
import Foundation
45
import GitHubCopilotService
56
import OpenAIService

Core/Sources/SuggestionWidget/SuggestionPanelContent/CodeBlock.swift renamed to Core/Sources/SharedUIComponents/CodeBlock.swift

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
import SwiftUI
22

3-
struct CodeBlock: View {
4-
let code: String
5-
let language: String
6-
let startLineIndex: Int
7-
let colorScheme: ColorScheme
8-
let commonPrecedingSpaceCount: Int
9-
let highlightedCode: [NSAttributedString]
10-
let firstLinePrecedingSpaceCount: Int
11-
let fontSize: Double
3+
public struct CodeBlock: View {
4+
public let code: String
5+
public let language: String
6+
public let startLineIndex: Int
7+
public let colorScheme: ColorScheme
8+
public let commonPrecedingSpaceCount: Int
9+
public let highlightedCode: [NSAttributedString]
10+
public let firstLinePrecedingSpaceCount: Int
11+
public let fontSize: Double
1212

13-
init(
13+
public init(
1414
code: String,
1515
language: String,
1616
startLineIndex: Int,
@@ -37,7 +37,7 @@ struct CodeBlock: View {
3737
highlightedCode = result.code
3838
}
3939

40-
var body: some View {
40+
public var body: some View {
4141
VStack(spacing: 2) {
4242
ForEach(0..<highlightedCode.endIndex, id: \.self) { index in
4343
HStack(alignment: .firstTextBaseline, spacing: 4) {

Core/Sources/SuggestionWidget/CopyButton.swift renamed to Core/Sources/SharedUIComponents/CopyButton.swift

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
import AppKit
22
import SwiftUI
33

4-
struct CopyButton: View {
5-
var copy: () -> Void
4+
public struct CopyButton: View {
5+
public var copy: () -> Void
66
@State var isCopied = false
7-
var body: some View {
7+
8+
public init(copy: @escaping () -> Void) {
9+
self.copy = copy
10+
}
11+
12+
public var body: some View {
813
Button(action: {
914
withAnimation(.linear(duration: 0.1)) {
1015
isCopied = true

Core/Sources/SuggestionWidget/CustomScrollView/CustomScrollView.swift renamed to Core/Sources/SharedUIComponents/CustomScrollView.swift

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
import AppKit
22
import Combine
3+
import Preferences
34
import SwiftUI
45

5-
struct CustomScrollViewHeightPreferenceKey: PreferenceKey {
6-
static var defaultValue: Double = 0
7-
static func reduce(value: inout Double, nextValue: () -> Double) {
6+
public struct CustomScrollViewHeightPreferenceKey: SwiftUI.PreferenceKey {
7+
public static var defaultValue: Double = 0
8+
public static func reduce(value: inout Double, nextValue: () -> Double) {
89
value = nextValue() + value
910
}
1011
}
1112

12-
struct CustomScrollViewUpdateHeightModifier: ViewModifier {
13-
func body(content: Content) -> some View {
13+
public struct CustomScrollViewUpdateHeightModifier: ViewModifier {
14+
public func body(content: Content) -> some View {
1415
content
1516
.background {
1617
GeometryReader { proxy in
@@ -25,12 +26,16 @@ struct CustomScrollViewUpdateHeightModifier: ViewModifier {
2526
}
2627

2728
/// Used to workaround a SwiftUI bug. https://github.com/intitni/CopilotForXcode/issues/122
28-
struct CustomScrollView<Content: View>: View {
29+
public struct CustomScrollView<Content: View>: View {
2930
@ViewBuilder var content: () -> Content
3031
@State var height: Double = 10
3132
@AppStorage(\.useCustomScrollViewWorkaround) var useNSScrollViewWrapper
3233

33-
var body: some View {
34+
public init(content: @escaping () -> Content) {
35+
self.content = content
36+
}
37+
38+
public var body: some View {
3439
if useNSScrollViewWrapper {
3540
List {
3641
content()

0 commit comments

Comments
 (0)