Skip to content

Commit 80ca5d6

Browse files
committed
Add ChatPanel
1 parent ae646e1 commit 80ca5d6

File tree

5 files changed

+167
-11
lines changed

5 files changed

+167
-11
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,40 @@
1+
import AppKit
2+
import SwiftUI
3+
14
enum Style {
25
static let panelHeight: Double = 300
36
static let panelWidth: Double = 450
47
static let widgetHeight: Double = 30
58
static var widgetWidth: Double { widgetHeight }
69
static let widgetPadding: Double = 4
710
}
11+
12+
extension Color {
13+
static var contentBackground: Color {
14+
Color(nsColor: NSColor(name: nil, dynamicProvider: { appearance in
15+
if appearance.isDarkMode {
16+
return #colorLiteral(red: 0.1580096483, green: 0.1730263829, blue: 0.2026666105, alpha: 1)
17+
}
18+
return .white
19+
}))
20+
}
21+
22+
static var userChatContentBackground: Color {
23+
Color(nsColor: NSColor(name: nil, dynamicProvider: { appearance in
24+
if appearance.isDarkMode {
25+
return #colorLiteral(red: 0.1777971793, green: 0.1670255649, blue: 0.2501594388, alpha: 1)
26+
}
27+
return #colorLiteral(red: 0.896820749, green: 0.8709097223, blue: 0.9766687925, alpha: 1)
28+
}))
29+
}
30+
}
31+
32+
extension NSAppearance {
33+
var isDarkMode: Bool {
34+
if self.bestMatch(from: [.darkAqua, .aqua]) == .darkAqua {
35+
return true
36+
} else {
37+
return false
38+
}
39+
}
40+
}
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
import MarkdownUI
2+
import SwiftUI
3+
4+
struct ChatPanel: View {
5+
@ObservedObject var viewModel: SuggestionPanelViewModel
6+
var chat: SuggestionPanelViewModel.Chat
7+
8+
var body: some View {
9+
ZStack(alignment: .topTrailing) {
10+
ScrollView {
11+
LazyVStack {
12+
ForEach(chat.history.reversed(), id: \.id) { message in
13+
Markdown(message.text)
14+
.markdownTheme(.gitHub.text {
15+
BackgroundColor(Color.clear)
16+
})
17+
.frame(maxWidth: .infinity, alignment: .leading)
18+
.padding()
19+
.background(
20+
RoundedRectangle(cornerRadius: 9, style: .continuous)
21+
.fill(
22+
message.isUser
23+
? Color.userChatContentBackground
24+
: Color.contentBackground
25+
)
26+
)
27+
.rotationEffect(Angle(degrees: 180))
28+
}
29+
}
30+
}
31+
.rotationEffect(Angle(degrees: 180))
32+
33+
// close button
34+
Button(action: {
35+
viewModel.isPanelDisplayed = false
36+
viewModel.content = .empty
37+
}) {
38+
Image(systemName: "xmark")
39+
.padding([.leading, .bottom], 16)
40+
.padding([.top, .trailing], 8)
41+
.foregroundColor(.white)
42+
}
43+
.buttonStyle(.plain)
44+
}
45+
.colorScheme(viewModel.colorScheme)
46+
}
47+
}
48+
49+
struct ChatPanel_Preview: PreviewProvider {
50+
static var previews: some View {
51+
ChatPanel(viewModel: .init(
52+
content: .empty,
53+
isPanelDisplayed: true
54+
), chat: .init(
55+
history: [
56+
.init(
57+
id: "1",
58+
isUser: true,
59+
text: "**Hello**"
60+
),
61+
.init(id: "2", isUser: false, text: "**Hey**! What can I do for you?"),
62+
.init(
63+
id: "3",
64+
isUser: true,
65+
text: #"""
66+
Please buy me a coffee!
67+
| Coffee | Milk |
68+
|--------|------|
69+
| Espresso | No |
70+
| Latte | Yes |
71+
72+
```swift
73+
func foo() {}
74+
```
75+
"""#
76+
),
77+
],
78+
isReceivingMessage: false
79+
))
80+
.frame(width: 450, height: 500)
81+
}
82+
}
83+
84+
struct ChatPanel_Light_Preview: PreviewProvider {
85+
static var previews: some View {
86+
ChatPanel(viewModel: .init(
87+
content: .empty,
88+
isPanelDisplayed: true,
89+
colorScheme: .light
90+
), chat: .init(
91+
history: [
92+
.init(
93+
id: "1",
94+
isUser: true,
95+
text: "**Hello**"
96+
),
97+
.init(id: "2", isUser: false, text: "**Hey**! What can I do for you?"),
98+
.init(
99+
id: "3",
100+
isUser: true,
101+
text: #"""
102+
Please buy me a coffee!
103+
| Coffee | Milk |
104+
|--------|------|
105+
| Espresso | No |
106+
| Latte | Yes |
107+
108+
```swift
109+
func foo() {}
110+
```
111+
"""#
112+
),
113+
],
114+
isReceivingMessage: false
115+
))
116+
.frame(width: 450, height: 500)
117+
}
118+
}

Core/Sources/SuggestionWidget/SuggestionPanelContent/CodeBlockSuggestionPanel.swift

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -78,16 +78,7 @@ struct CodeBlockSuggestionPanel: View {
7878
CodeBlock(suggestion: suggestion)
7979
.frame(maxWidth: .infinity)
8080
}
81-
.background(Color(nsColor: {
82-
switch viewModel.colorScheme {
83-
case .dark:
84-
return #colorLiteral(red: 0.1580096483, green: 0.1730263829, blue: 0.2026666105, alpha: 1)
85-
case .light:
86-
return .white
87-
@unknown default:
88-
return .white
89-
}
90-
}()))
81+
.background(Color.contentBackground)
9182

9283
ToolBar(viewModel: viewModel, suggestion: suggestion)
9384
}

Core/Sources/SuggestionWidget/SuggestionPanelContent/ErrorPanel.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import SwiftUI
22

33
struct ErrorPanel: View {
4-
@ObservedObject var viewModel: SuggestionPanelViewModel
4+
var viewModel: SuggestionPanelViewModel
55
var description: String
66

77
var body: some View {

Core/Sources/SuggestionWidget/SuggestionPanelView.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,21 @@ final class SuggestionPanelViewModel: ObservableObject {
1616
)
1717
}
1818

19+
struct Chat: Equatable {
20+
struct ChatMessage: Equatable {
21+
var id: String
22+
var isUser: Bool
23+
var text: String
24+
}
25+
26+
var history: [ChatMessage]
27+
var isReceivingMessage: Bool
28+
}
29+
1930
enum Content: Equatable {
2031
case empty
2132
case suggestion(Suggestion)
33+
case chat(Chat)
2234
case error(String)
2335
}
2436

@@ -70,6 +82,8 @@ struct SuggestionPanelView: View {
7082
CodeBlockSuggestionPanel(viewModel: viewModel, suggestion: suggestion)
7183
case let .error(description):
7284
ErrorPanel(viewModel: viewModel, description: description)
85+
case let .chat(chat):
86+
ChatPanel(viewModel: viewModel, chat: chat)
7387
}
7488
}
7589
.frame(maxWidth: .infinity, maxHeight: Style.panelHeight)

0 commit comments

Comments
 (0)