@@ -19,18 +19,18 @@ class AppDelegate: NSObject, NSApplicationDelegate {
19
19
@Default ( . showRequested) var showRequested
20
20
21
21
@Default ( . showAvatar) var showAvatar
22
- @Default ( . showChecks) var showChecks
23
22
@Default ( . showLabels) var showLabels
24
23
25
24
@Default ( . refreshRate) var refreshRate
25
+ @Default ( . buildType) var buildType
26
26
27
27
@Default ( . githubUsername) var githubUsername
28
28
@FromKeychain ( . githubToken) var githubToken
29
-
29
+
30
30
let ghClient = GitHubClient ( )
31
31
var statusBarItem : NSStatusItem = NSStatusBar . system. statusItem ( withLength: NSStatusItem . variableLength)
32
32
let menu : NSMenu = NSMenu ( )
33
-
33
+
34
34
var preferencesWindow : NSWindow !
35
35
var aboutWindow : NSWindow !
36
36
@@ -106,15 +106,15 @@ extension AppDelegate {
106
106
group. leave ( )
107
107
}
108
108
}
109
-
109
+
110
110
if showCreated {
111
111
group. enter ( )
112
112
ghClient. getCreatedPulls ( ) { pulls in
113
113
createdPulls? . append ( contentsOf: pulls)
114
114
group. leave ( )
115
115
}
116
116
}
117
-
117
+
118
118
if showRequested {
119
119
group. enter ( )
120
120
ghClient. getReviewRequestedPulls ( ) { pulls in
@@ -126,7 +126,7 @@ extension AppDelegate {
126
126
group. notify ( queue: . main) {
127
127
128
128
let isOneSelected = ( self . showAssigned. intValue + self . showCreated. intValue + self . showRequested. intValue) == 1
129
-
129
+
130
130
131
131
if let assignedPulls = assignedPulls, let createdPulls = createdPulls, let reviewRequestedPulls = reviewRequestedPulls {
132
132
@@ -150,9 +150,9 @@ extension AppDelegate {
150
150
if isOneSelected {
151
151
self . statusBarItem. button? . title = String ( createdPulls. count)
152
152
}
153
-
153
+
154
154
}
155
-
155
+
156
156
if self . showRequested && !reviewRequestedPulls. isEmpty {
157
157
self . menu. addItem ( NSMenuItem ( title: " Review Requested ( \( reviewRequestedPulls. count) ) " , action: nil , keyEquivalent: " " ) )
158
158
for pull in reviewRequestedPulls {
@@ -162,7 +162,7 @@ extension AppDelegate {
162
162
if isOneSelected {
163
163
self . statusBarItem. button? . title = String ( reviewRequestedPulls. count)
164
164
}
165
-
165
+
166
166
}
167
167
168
168
@@ -174,21 +174,28 @@ extension AppDelegate {
174
174
func createMenuItem( pull: Edge ) -> NSMenuItem {
175
175
let issueItem = NSMenuItem ( title: " " , action: #selector( self . openLink) , keyEquivalent: " " )
176
176
177
- let issueItemTitle = NSMutableAttributedString ( string: pull. node. title. trunc ( length: 50 ) )
177
+ let issueItemTitle = NSMutableAttributedString ( string: " " )
178
+ . appendString ( string: pull. node. isReadByViewer ? " " : " ⏺ " , color: . systemBlue)
179
+
180
+ if ( pull. node. isDraft) {
181
+ issueItemTitle
182
+ . appendIcon ( iconName: " git-draft-pull-request " , color: NSColor . secondaryLabelColor)
183
+ }
184
+
185
+ issueItemTitle
186
+ . appendString ( string: pull. node. title. trunc ( length: 50 ) , color: NSColor ( . primary) )
178
187
. appendString ( string: " # " + String( pull. node. number) )
179
188
. appendSeparator ( )
180
- . appendIcon ( iconName: pull. node. isDraft ? " git-draft-pull-request " : " git-pull-request " , color: pull. node. isDraft ? NSColor . secondaryLabelColor : NSColor ( named: " green " ) !)
181
- . appendString ( string: pull. node. isDraft ? " Draft " : " Open " , color: pull. node. isDraft ? NSColor . secondaryLabelColor : NSColor ( named: " green " ) !)
182
189
183
190
issueItemTitle. appendNewLine ( )
184
-
191
+
185
192
issueItemTitle
186
193
. appendIcon ( iconName: " repo " )
187
194
. appendString ( string: pull. node. repository. name)
188
195
. appendSeparator ( )
189
196
. appendIcon ( iconName: " person " )
190
197
. appendString ( string: pull. node. author. login)
191
-
198
+
192
199
if !pull. node. labels. nodes. isEmpty && self . showLabels {
193
200
issueItemTitle
194
201
. appendNewLine ( )
@@ -197,7 +204,7 @@ extension AppDelegate {
197
204
issueItemTitle
198
205
. appendString ( string: label. name, color: hexColor ( hex: label. color) , fontSize: NSFont . smallSystemFontSize)
199
206
. appendSeparator ( )
200
- }
207
+ }
201
208
}
202
209
203
210
issueItemTitle. appendNewLine ( )
@@ -212,7 +219,7 @@ extension AppDelegate {
212
219
. appendSeparator ( )
213
220
. appendIcon ( iconName: " calendar " )
214
221
. appendString ( string: pull. node. createdAt. getElapsedInterval ( ) )
215
-
222
+
216
223
if showAvatar {
217
224
var image = NSImage ( )
218
225
if let imageURL = pull. node. author. avatarUrl {
@@ -229,39 +236,90 @@ extension AppDelegate {
229
236
230
237
231
238
if let commits = pull. node. commits {
232
- if commits. nodes [ 0 ] . commit. checkSuites. nodes. count > 0 {
233
- issueItem. submenu = NSMenu ( )
234
- issueItemTitle
235
- . appendSeparator ( )
236
- . appendIcon ( iconName: " checklist " , color: NSColor . secondaryLabelColor)
239
+
240
+ if let checkSuites = commits. nodes [ 0 ] . commit. checkSuites {
241
+
242
+ if checkSuites. nodes. count > 0 {
243
+ issueItem. submenu = NSMenu ( )
244
+ issueItemTitle
245
+ . appendSeparator ( )
246
+ . appendIcon ( iconName: " checklist " , color: NSColor . secondaryLabelColor)
247
+ }
248
+ for checkSuite in checkSuites. nodes {
249
+
250
+ if checkSuite. checkRuns. nodes. count > 0 {
251
+ issueItem. submenu? . addItem ( withTitle: checkSuite. app? . name ?? " empty " , action: nil , keyEquivalent: " " )
252
+ }
253
+ for check in checkSuite. checkRuns. nodes {
254
+
255
+ let buildItem = NSMenuItem ( title: check. name, action: #selector( self . openLink) , keyEquivalent: " " )
256
+ buildItem. representedObject = check. detailsUrl
257
+ buildItem. toolTip = check. conclusion
258
+ if check. conclusion == " SUCCESS " {
259
+ buildItem. image = NSImage ( named: " check-circle-fill " ) !. tint ( color: NSColor ( named: " green " ) !)
260
+ issueItemTitle. appendIcon ( iconName: " dot-fill " , color: NSColor ( named: " green " ) !)
261
+ } else if check. conclusion == " FAILURE " {
262
+ buildItem. image = NSImage ( named: " x-circle-fill " ) !. tint ( color: NSColor ( named: " red " ) !)
263
+ issueItemTitle. appendIcon ( iconName: " dot-fill " , color: NSColor ( named: " red " ) !)
264
+ } else if check. conclusion == " ACTION_REQUIRED " {
265
+ buildItem. image = NSImage ( named: " issue-draft " ) !. tint ( color: NSColor ( named: " yellow " ) !)
266
+ issueItemTitle. appendIcon ( iconName: " dot-fill " , color: NSColor ( named: " yellow " ) !)
267
+ } else {
268
+ buildItem. image = NSImage ( named: " question " ) !. tint ( color: NSColor . gray)
269
+ issueItemTitle. appendIcon ( iconName: " dot-fill " , color: NSColor . gray)
270
+ }
271
+
272
+ issueItem. submenu? . addItem ( buildItem)
273
+ }
274
+ }
237
275
}
238
- for checkSuite in commits. nodes [ 0 ] . commit. checkSuites. nodes {
276
+
277
+ else if let statusCheckRollup = commits. nodes [ 0 ] . commit. statusCheckRollup {
239
278
240
- if checkSuite. checkRuns. nodes. count > 0 {
241
- issueItem. submenu? . addItem ( withTitle: checkSuite. app? . name ?? " empty " , action: nil , keyEquivalent: " " )
279
+ if statusCheckRollup. contexts. nodes. count > 0 {
280
+ issueItem. submenu = NSMenu ( )
281
+ issueItemTitle
282
+ . appendSeparator ( )
283
+ . appendIcon ( iconName: " checklist " , color: NSColor . secondaryLabelColor)
242
284
}
243
- for check in checkSuite. checkRuns. nodes {
285
+
286
+ for check in statusCheckRollup. contexts. nodes {
287
+ let itemTitle = NSMutableAttributedString ( )
288
+ itemTitle. appendString ( string: check. name ?? check. context ?? " <empty> " , color: NSColor ( . primary) )
289
+ itemTitle. appendNewLine ( )
290
+ . appendString ( string: check. description ?? check. title ?? " <empty> " , color: NSColor ( . secondary) )
291
+
292
+ let buildItem = NSMenuItem ( title: " " , action: #selector( AppDelegate . openLink) , keyEquivalent: " " )
293
+ buildItem. attributedTitle = itemTitle
294
+
295
+ buildItem. representedObject = check. detailsUrl ?? URL . init ( string: check. targetUrl ?? " " )
244
296
245
- let buildItem = NSMenuItem ( title: check. name, action: #selector( self . openLink) , keyEquivalent: " " )
246
- buildItem. representedObject = check. detailsUrl
247
- buildItem. toolTip = check. conclusion
248
- if check. conclusion == " SUCCESS " {
297
+ buildItem. toolTip = check. conclusion ?? check. state ?? " "
298
+
299
+ let status = check. conclusion ?? check. state ?? " "
300
+ switch status {
301
+ case " SUCCESS " :
249
302
buildItem. image = NSImage ( named: " check-circle-fill " ) !. tint ( color: NSColor ( named: " green " ) !)
250
303
issueItemTitle. appendIcon ( iconName: " dot-fill " , color: NSColor ( named: " green " ) !)
251
- } else if check . conclusion == " FAILURE " {
304
+ case " FAILURE " :
252
305
buildItem. image = NSImage ( named: " x-circle-fill " ) !. tint ( color: NSColor ( named: " red " ) !)
253
306
issueItemTitle. appendIcon ( iconName: " dot-fill " , color: NSColor ( named: " red " ) !)
254
- } else if check . conclusion == " ACTION_REQUIRED " {
307
+ case " PENDING " :
255
308
buildItem. image = NSImage ( named: " issue-draft " ) !. tint ( color: NSColor ( named: " yellow " ) !)
256
309
issueItemTitle. appendIcon ( iconName: " dot-fill " , color: NSColor ( named: " yellow " ) !)
257
- } else {
310
+ default :
258
311
buildItem. image = NSImage ( named: " question " ) !. tint ( color: NSColor . gray)
259
312
issueItemTitle. appendIcon ( iconName: " dot-fill " , color: NSColor . gray)
313
+
260
314
}
261
315
262
316
issueItem. submenu? . addItem ( buildItem)
263
317
}
318
+
319
+
320
+
264
321
}
322
+
265
323
}
266
324
267
325
issueItem. attributedTitle = issueItemTitle
@@ -289,7 +347,7 @@ extension AppDelegate {
289
347
preferencesWindow. close ( )
290
348
}
291
349
preferencesWindow = NSWindow (
292
- contentRect: NSRect ( x: 0 , y: 0 , width: 500 , height: 400 ) ,
350
+ contentRect: NSRect ( x: 0 , y: 0 , width: 500 , height: 500 ) ,
293
351
styleMask: [ . closable, . titled] ,
294
352
backing: . buffered,
295
353
defer: false
@@ -299,7 +357,7 @@ extension AppDelegate {
299
357
preferencesWindow. contentView = NSHostingView ( rootView: contentView)
300
358
preferencesWindow. makeKeyAndOrderFront ( nil )
301
359
preferencesWindow. styleMask. remove ( . resizable)
302
-
360
+
303
361
// allow the preference window can be focused automatically when opened
304
362
NSApplication . shared. activate ( ignoringOtherApps: true )
305
363
@@ -328,7 +386,7 @@ extension AppDelegate {
328
386
aboutWindow. contentView = NSHostingView ( rootView: contentView)
329
387
aboutWindow. makeKeyAndOrderFront ( nil )
330
388
aboutWindow. styleMask. remove ( . resizable)
331
-
389
+
332
390
// allow the preference window can be focused automatically when opened
333
391
NSApplication . shared. activate ( ignoringOtherApps: true )
334
392
0 commit comments