Skip to content

Commit bbdeaab

Browse files
ADD: open handler callback for custom logic
1 parent f8a17a9 commit bbdeaab

3 files changed

Lines changed: 45 additions & 21 deletions

File tree

Sources/WelcomeWindow/Views/RecentsListView.swift

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,20 @@ public struct RecentsListView: View {
2020

2121
@FocusState.Binding private var focusedField: FocusTarget?
2222
private let dismissWindow: () -> Void
23+
private let openHandler: WelcomeOpenHandler
2324

2425
public init(
2526
recentProjects: Binding<[URL]>,
2627
selection: Binding<Set<URL>>,
2728
focusedField: FocusState<FocusTarget?>.Binding,
28-
dismissWindow: @escaping () -> Void
29+
dismissWindow: @escaping () -> Void,
30+
openHandler: @escaping WelcomeOpenHandler
2931
) {
3032
self._recentProjects = recentProjects
3133
self._selection = selection
3234
self._focusedField = focusedField
3335
self.dismissWindow = dismissWindow
36+
self.openHandler = openHandler
3437
}
3538

3639
private var isFocused: Bool {
@@ -70,11 +73,7 @@ public struct RecentsListView: View {
7073
}
7174
}
7275
} primaryAction: { items in
73-
for url in items {
74-
NSDocumentController.shared.openDocument(at: url) {
75-
dismissWindow()
76-
}
77-
}
76+
openHandler(Array(items), dismissWindow)
7877
}
7978
.onCopyCommand {
8079
selection.map { NSItemProvider(object: $0.path(percentEncoded: false) as NSString) }
@@ -84,11 +83,7 @@ public struct RecentsListView: View {
8483
}
8584
.background {
8685
Button("") {
87-
selection.forEach { url in
88-
NSDocumentController.shared.openDocument(at: url) {
89-
dismissWindow()
90-
}
91-
}
86+
openHandler(Array(selection), dismissWindow)
9287
}
9388
.keyboardShortcut(.defaultAction)
9489
.hidden()

Sources/WelcomeWindow/Views/WelcomeWindow.swift

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ public struct WelcomeWindow<RecentsView: View, SubtitleView: View>: Scene {
1515
private let customRecentsList: ((_ dismissWindow: @escaping () -> Void) -> RecentsView)?
1616
private let onDrop: ((_ url: URL, _ dismiss: @escaping () -> Void) -> Void)?
1717
private let subtitleView: (() -> SubtitleView)?
18+
private let openHandler: WelcomeOpenHandler?
1819

1920
let iconImage: Image?
2021
let title: String?
@@ -33,14 +34,16 @@ public struct WelcomeWindow<RecentsView: View, SubtitleView: View>: Scene {
3334
@ActionsBuilder actions: @escaping (_ dismissWindow: @escaping () -> Void) -> WelcomeActions,
3435
customRecentsList: ((_ dismissWindow: @escaping () -> Void) -> RecentsView)? = nil,
3536
subtitleView: (() -> SubtitleView)? = nil,
36-
onDrop: ((_ url: URL, _ dismiss: @escaping () -> Void) -> Void)? = nil
37+
onDrop: ((_ url: URL, _ dismiss: @escaping () -> Void) -> Void)? = nil,
38+
openHandler: WelcomeOpenHandler? = nil
3739
) {
3840
self.iconImage = iconImage
3941
self.title = title
4042
self.buildActions = actions
4143
self.customRecentsList = customRecentsList
4244
self.subtitleView = subtitleView
4345
self.onDrop = onDrop
46+
self.openHandler = openHandler
4447
}
4548

4649
public var body: some Scene {
@@ -52,7 +55,8 @@ public struct WelcomeWindow<RecentsView: View, SubtitleView: View>: Scene {
5255
subtitleView: subtitleView,
5356
buildActions: buildActions,
5457
onDrop: onDrop,
55-
customRecentsList: customRecentsList
58+
customRecentsList: customRecentsList,
59+
openHandler: openHandler
5660
)
5761
.frame(width: 740, height: isMacOS26 ? 460 - 28 : 460)
5862
.task {
@@ -71,6 +75,8 @@ public struct WelcomeWindow<RecentsView: View, SubtitleView: View>: Scene {
7175
}
7276
}
7377

78+
public typealias WelcomeOpenHandler = @MainActor (_ urls: [URL], _ dismiss: @escaping () -> Void) -> Void
79+
7480
// ──────────────────────────────────────────────────────────────
7581
// 1) NEITHER a custom recents list NOR a subtitle view
7682
// ──────────────────────────────────────────────────────────────
@@ -81,15 +87,17 @@ extension WelcomeWindow where RecentsView == EmptyView, SubtitleView == EmptyVie
8187
iconImage: Image? = nil,
8288
title: String? = nil,
8389
@ActionsBuilder actions: @escaping (_ dismissWindow: @escaping () -> Void) -> WelcomeActions,
84-
onDrop: ((_ url: URL, _ dismissWindow: @escaping () -> Void) -> Void)? = nil
90+
onDrop: ((_ url: URL, _ dismissWindow: @escaping () -> Void) -> Void)? = nil,
91+
openHandler: WelcomeOpenHandler? = nil
8592
) {
8693
self.init(
8794
iconImage: iconImage,
8895
title: title,
8996
actions: actions,
9097
customRecentsList: nil,
9198
subtitleView: nil,
92-
onDrop: onDrop
99+
onDrop: onDrop,
100+
openHandler: openHandler
93101
)
94102
}
95103
}
@@ -105,15 +113,17 @@ extension WelcomeWindow where RecentsView == EmptyView {
105113
title: String? = nil,
106114
subtitleView: @escaping () -> SubtitleView,
107115
@ActionsBuilder actions: @escaping (_ dismissWindow: @escaping () -> Void) -> WelcomeActions,
108-
onDrop: ((_ url: URL, _ dismissWindow: @escaping () -> Void) -> Void)? = nil
116+
onDrop: ((_ url: URL, _ dismissWindow: @escaping () -> Void) -> Void)? = nil,
117+
openHandler: WelcomeOpenHandler? = nil
109118
) {
110119
self.init(
111120
iconImage: iconImage,
112121
title: title,
113122
actions: actions,
114123
customRecentsList: nil,
115124
subtitleView: subtitleView,
116-
onDrop: onDrop
125+
onDrop: onDrop,
126+
openHandler: openHandler
117127
)
118128
}
119129
}
@@ -129,15 +139,17 @@ extension WelcomeWindow where SubtitleView == EmptyView {
129139
title: String? = nil,
130140
@ActionsBuilder actions: @escaping (_ dismissWindow: @escaping () -> Void) -> WelcomeActions,
131141
customRecentsList: ((_ dismissWindow: @escaping () -> Void) -> RecentsView)? = nil,
132-
onDrop: ((_ url: URL, _ dismissWindow: @escaping () -> Void) -> Void)? = nil
142+
onDrop: ((_ url: URL, _ dismissWindow: @escaping () -> Void) -> Void)? = nil,
143+
openHandler: WelcomeOpenHandler? = nil
133144
) {
134145
self.init(
135146
iconImage: iconImage,
136147
title: title,
137148
actions: actions,
138149
customRecentsList: customRecentsList,
139150
subtitleView: nil,
140-
onDrop: onDrop
151+
onDrop: onDrop,
152+
openHandler: openHandler
141153
)
142154
}
143155
}

Sources/WelcomeWindow/Views/WelcomeWindowView.swift

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ public struct WelcomeWindowView<RecentsView: View, SubtitleView: View>: View {
2525
private let onDrop: ((_ url: URL, _ dismiss: @escaping () -> Void) -> Void)?
2626
private let customRecentsList: ((_ dismissWindow: @escaping () -> Void) -> RecentsView)?
2727
private let subtitleView: (() -> SubtitleView)?
28+
private let openHandler: WelcomeOpenHandler?
2829

2930
let iconImage: Image?
3031
let title: String?
@@ -35,19 +36,34 @@ public struct WelcomeWindowView<RecentsView: View, SubtitleView: View>: View {
3536
subtitleView: (() -> SubtitleView)? = nil,
3637
buildActions: @escaping (_ dismissWindow: @escaping () -> Void) -> WelcomeActions,
3738
onDrop: ((_ url: URL, _ dismiss: @escaping () -> Void) -> Void)? = nil,
38-
customRecentsList: ((_ dismissWindow: @escaping () -> Void) -> RecentsView)? = nil
39+
customRecentsList: ((_ dismissWindow: @escaping () -> Void) -> RecentsView)? = nil,
40+
openHandler: WelcomeOpenHandler? = nil
3941
) {
4042
self.iconImage = iconImage
4143
self.title = title
4244
self.subtitleView = subtitleView
4345
self.buildActions = buildActions
4446
self.onDrop = onDrop
4547
self.customRecentsList = customRecentsList
48+
self.openHandler = openHandler
49+
}
50+
51+
private func defaultOpenHandler(urls: [URL], dismiss: @escaping () -> Void) {
52+
var dismissed = false
53+
for url in urls {
54+
NSDocumentController.shared.openDocument(at: url) {
55+
if !dismissed {
56+
dismissed = true
57+
dismiss()
58+
}
59+
}
60+
}
4661
}
4762

4863
public var body: some View {
4964
let dismiss = dismissWindow.callAsFunction
5065
let actions = buildActions(dismiss)
66+
let effectiveOpen = openHandler ?? defaultOpenHandler
5167

5268
return HStack(spacing: 0) {
5369
WelcomeView(
@@ -67,7 +83,8 @@ public struct WelcomeWindowView<RecentsView: View, SubtitleView: View>: View {
6783
recentProjects: $recentProjects,
6884
selection: $selection,
6985
focusedField: $focusedField,
70-
dismissWindow: dismiss
86+
dismissWindow: dismiss,
87+
openHandler: effectiveOpen
7188
)
7289
}
7390
}

0 commit comments

Comments
 (0)