forked from github/CopilotForXcode
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathFunctionMessage.swift
More file actions
135 lines (122 loc) · 5 KB
/
FunctionMessage.swift
File metadata and controls
135 lines (122 loc) · 5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import Foundation
import SwiftUI
import ChatService
import SharedUIComponents
import ComposableArchitecture
struct FunctionMessage: View {
let chat: StoreOf<Chat>
let id: String
let text: String
@AppStorage(\.chatFontSize) var chatFontSize
@Environment(\.openURL) private var openURL
private let displayFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateStyle = .long
formatter.timeStyle = .short
return formatter
}()
private func extractDate(from text: String) -> Date? {
guard let match = (try? NSRegularExpression(pattern: "until (.*?) for"))?
.firstMatch(in: text, options: [], range: NSRange(location: 0, length: text.utf16.count)),
let dateRange = Range(match.range(at: 1), in: text) else {
return nil
}
let dateString = String(text[dateRange])
let formatter = DateFormatter()
formatter.dateFormat = "M/d/yyyy, h:mm:ss a"
return formatter.date(from: dateString)
}
var body: some View {
VStack(alignment: .leading, spacing: 8) {
HStack {
Image("CopilotLogo")
.resizable()
.renderingMode(.template)
.scaledToFill()
.frame(width: 12, height: 12)
.overlay(
Circle()
.stroke(Color(nsColor: .separatorColor), lineWidth: 1)
.frame(width: 24, height: 24)
)
.padding(.leading, 8)
Text("GitHub Copilot")
.font(.system(size: 13))
.fontWeight(.semibold)
.padding(4)
Spacer()
}
VStack(alignment: .leading, spacing: 16) {
Text("You've reached your monthly chat limit for GitHub Copilot Free.")
.font(.system(size: 13))
.fontWeight(.medium)
if let date = extractDate(from: text) {
Text("Upgrade to Copilot Pro with a 30-day free trial or wait until \(displayFormatter.string(from: date)) for your limit to reset.")
.font(.system(size: 13))
}
Button("Update to Copilot Pro") {
if let url = URL(string: "https://github.com/github-copilot/signup/copilot_individual") {
openURL(url)
}
}
.buttonStyle(.borderedProminent)
.controlSize(.large)
}
.padding(.vertical, 10)
.padding(.horizontal, 12)
.overlay(
RoundedRectangle(cornerRadius: 6)
.stroke(Color(nsColor: .separatorColor), lineWidth: 1)
)
// HStack {
// Button(action: {
// // Add your refresh action here
// }) {
// Image(systemName: "arrow.clockwise")
// .resizable()
// .aspectRatio(contentMode: .fit)
// .frame(width: 14, height: 14)
// .frame(width: 20, height: 20, alignment: .center)
// .foregroundColor(.secondary)
// .background(
// .regularMaterial,
// in: RoundedRectangle(cornerRadius: 4, style: .circular)
// )
// .padding(4)
// }
// .buttonStyle(.borderless)
//
// DownvoteButton { rating in
// chat.send(.downvote(id, rating))
// }
//
// Button(action: {
// // Add your more options action here
// }) {
// Image(systemName: "ellipsis")
// .resizable()
// .aspectRatio(contentMode: .fit)
// .frame(width: 14, height: 14)
// .frame(width: 20, height: 20, alignment: .center)
// .foregroundColor(.secondary)
// .background(
// .regularMaterial,
// in: RoundedRectangle(cornerRadius: 4, style: .circular)
// )
// .padding(4)
// }
// .buttonStyle(.borderless)
// }
}
.padding(.vertical, 12)
}
}
#Preview {
FunctionMessage(
chat: .init(initialState: .init(), reducer: { Chat(service: ChatService.service()) }),
id: "1",
text: "You've reached your monthly chat limit. Upgrade to Copilot Pro (30-day free trial) or wait until 1/17/2025, 8:00:00 AM for your limit to reset."
)
.padding()
.fixedSize()
}