Skip to content

Commit 789988a

Browse files
authored
Merge pull request #993 from lukepistrol/feat/welcome-window-refactoring
[chore]: welcome window refactoring
2 parents 452da17 + e476a7a commit 789988a

4 files changed

Lines changed: 252 additions & 220 deletions

File tree

CodeEdit/Features/Welcome/Views/RecentProjectItem.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,15 @@ struct RecentProjectItem: View {
2727
.aspectRatio(contentMode: .fit)
2828
.frame(width: 32, height: 32)
2929
VStack(alignment: .leading) {
30-
Text(projectPath.components(separatedBy: "/").last ?? "").font(.system(size: 13))
30+
Text(projectPath.components(separatedBy: "/").last ?? "")
31+
.font(.system(size: 13))
3132
.lineLimit(1)
3233
Text(projectPath.abbreviatingWithTildeInPath())
3334
.font(.system(size: 11))
3435
.lineLimit(1)
3536
.truncationMode(.head)
36-
}.padding(.trailing, 15)
37+
}
38+
.padding(.trailing, 15)
3739
Spacer()
3840
}
3941
.contentShape(Rectangle())

CodeEdit/Features/Welcome/Views/RecentProjectsView.swift

Lines changed: 140 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -30,68 +30,9 @@ struct RecentProjectsView: View {
3030
self.recentProjectPaths = UserDefaults.standard.array(forKey: "recentProjectPaths") as? [String] ?? []
3131
}
3232

33-
private var emptyView: some View {
34-
VStack {
35-
Spacer()
36-
Text(NSLocalizedString("No Recent Projects", comment: ""))
37-
.font(.system(size: 20))
38-
Spacer()
39-
}
40-
}
41-
42-
func contextMenuShowInFinder(projectPath: String) -> some View {
43-
Group {
44-
Button(NSLocalizedString("Show in Finder", comment: "")) {
45-
if selectedProjectPaths.contains(projectPath) {
46-
self.selectedProjectPaths.forEach { projectPath in
47-
guard let url = URL(string: "file://\(projectPath)") else {
48-
return
49-
}
50-
NSWorkspace.shared.activateFileViewerSelecting([url])
51-
}
52-
} else {
53-
guard let url = URL(string: "file://\(projectPath)") else {
54-
return
55-
}
56-
NSWorkspace.shared.activateFileViewerSelecting([url])
57-
}
58-
}
59-
}
60-
}
61-
62-
func contextMenuCopy(path: String) -> some View {
63-
Group {
64-
Button(NSLocalizedString("Copy Path", comment: "")) {
65-
let pasteboard = NSPasteboard.general
66-
pasteboard.declareTypes([.string], owner: nil)
67-
pasteboard.setString(path, forType: .string)
68-
}
69-
}
70-
}
71-
72-
func contextMenuDelete(projectPath: String) -> some View {
73-
Group {
74-
Button(NSLocalizedString("Remove from Recent Projects", comment: "")) {
75-
if selectedProjectPaths.contains(projectPath) {
76-
self.selectedProjectPaths.forEach { projectPath in
77-
deleteFromRecent(item: projectPath)
78-
}
79-
} else {
80-
deleteFromRecent(item: projectPath)
81-
}
82-
}
83-
}
84-
}
85-
8633
func deleteFromRecent(item: String) {
87-
self.recentProjectPaths.removeAll {
88-
$0 == item
89-
}
90-
91-
UserDefaults.standard.set(
92-
self.recentProjectPaths,
93-
forKey: "recentProjectPaths"
94-
)
34+
self.recentProjectPaths.removeAll { $0 == item }
35+
UserDefaults.standard.set(self.recentProjectPaths, forKey: "recentProjectPaths")
9536
}
9637

9738
func deleteProject(projectPath: String) {
@@ -138,61 +79,10 @@ struct RecentProjectsView: View {
13879
ZStack {
13980
RecentProjectItem(projectPath: projectPath)
14081
.frame(width: 300)
141-
.highPriorityGesture(TapGesture(count: 2).onEnded {
142-
openProject(projectPath: projectPath)
143-
})
144-
.gesture(TapGesture().onEnded {
145-
if NSEvent.modifierFlags.contains(.command) {
146-
self.lastSelectedProjectPath = projectPath
147-
selectedProjectPaths.insert(projectPath)
148-
} else if NSEvent.modifierFlags.contains(.shift) {
149-
if let lastIndex = recentProjectPaths.firstIndex(of: lastSelectedProjectPath),
150-
let currentIndex = recentProjectPaths.firstIndex(of: projectPath) {
151-
if currentIndex > lastIndex {
152-
let projectPaths = Array(recentProjectPaths[lastIndex..<currentIndex+1])
153-
selectedProjectPaths = selectedProjectPaths.union(projectPaths)
154-
} else {
155-
let projectPaths = Array(recentProjectPaths[currentIndex..<lastIndex+1])
156-
selectedProjectPaths = selectedProjectPaths.union(projectPaths)
157-
}
158-
}
159-
} else {
160-
self.lastSelectedProjectPath = projectPath
161-
selectedProjectPaths = [projectPath]
162-
}
163-
})
164-
.contextMenu {
165-
contextMenuShowInFinder(projectPath: projectPath)
166-
167-
if !selectedProjectPaths.contains(projectPath) {
168-
contextMenuCopy(path: projectPath)
169-
.keyboardShortcut(mgr.named(with: "copy").keyboardShortcut)
170-
}
171-
172-
Divider()
173-
contextMenuDelete(projectPath: projectPath)
174-
.keyboardShortcut(.init(.delete))
175-
}
176-
177-
Button("") {
178-
deleteProject(projectPath: projectPath)
179-
}
180-
.buttonStyle(.borderless)
181-
.keyboardShortcut(.init(.delete))
182-
183-
Button("") {
184-
let pasteboard = NSPasteboard.general
185-
pasteboard.declareTypes([.string], owner: nil)
186-
pasteboard.setString(projectPath, forType: .string)
187-
}
188-
.buttonStyle(.borderless)
189-
.keyboardShortcut(mgr.named(with: "copy").keyboardShortcut)
190-
191-
Button("") {
192-
openProject(projectPath: projectPath)
193-
}
194-
.buttonStyle(.borderless)
195-
.keyboardShortcut(.defaultAction)
82+
.highPriorityGesture(doubleTapGesture(projectPath))
83+
.gesture(singleTapGesture(projectPath))
84+
.contextMenu { contextMenu(projectPath) }
85+
keyboardShortcutButtons(projectPath)
19686
}
19787
}
19888
.listStyle(.sidebar)
@@ -211,6 +101,140 @@ struct RecentProjectsView: View {
211101
// onAppear is called once, and therafter never again,
212102
// since the window is never release from memory.
213103
updateRecentProjects()
104+
105+
// initially select the first item
106+
if let firstProject = recentProjectPaths.first {
107+
print(firstProject)
108+
self.lastSelectedProjectPath = firstProject
109+
self.selectedProjectPaths = [firstProject]
110+
}
111+
}
112+
}
113+
114+
private var emptyView: some View {
115+
VStack {
116+
Spacer()
117+
Text(NSLocalizedString("No Recent Projects", comment: ""))
118+
.font(.system(size: 20))
119+
Spacer()
120+
}
121+
}
122+
123+
// MARK: Gestures
124+
125+
private func doubleTapGesture(_ projectPath: String) -> some Gesture {
126+
TapGesture(count: 2)
127+
.onEnded {
128+
openProject(projectPath: projectPath)
129+
}
130+
}
131+
132+
private func singleTapGesture(_ projectPath: String) -> some Gesture {
133+
TapGesture()
134+
.onEnded {
135+
if NSEvent.modifierFlags.contains(.command) {
136+
self.lastSelectedProjectPath = projectPath
137+
selectedProjectPaths.insert(projectPath)
138+
} else if NSEvent.modifierFlags.contains(.shift) {
139+
if let lastIndex = recentProjectPaths.firstIndex(of: lastSelectedProjectPath),
140+
let currentIndex = recentProjectPaths.firstIndex(of: projectPath) {
141+
if currentIndex > lastIndex {
142+
let projectPaths = Array(recentProjectPaths[lastIndex..<currentIndex+1])
143+
selectedProjectPaths = selectedProjectPaths.union(projectPaths)
144+
} else {
145+
let projectPaths = Array(recentProjectPaths[currentIndex..<lastIndex+1])
146+
selectedProjectPaths = selectedProjectPaths.union(projectPaths)
147+
}
148+
}
149+
} else {
150+
self.lastSelectedProjectPath = projectPath
151+
selectedProjectPaths = [projectPath]
152+
}
153+
}
154+
}
155+
156+
// MARK: Context Menu
157+
158+
@ViewBuilder
159+
private func contextMenu(_ projectPath: String) -> some View {
160+
contextMenuShowInFinder(projectPath)
161+
162+
if !selectedProjectPaths.contains(projectPath) {
163+
contextMenuCopy(projectPath)
164+
.keyboardShortcut(mgr.named(with: "copy").keyboardShortcut)
165+
}
166+
167+
Divider()
168+
contextMenuDelete(projectPath)
169+
.keyboardShortcut(.init(.delete))
170+
}
171+
172+
private func contextMenuShowInFinder(_ projectPath: String) -> some View {
173+
Group {
174+
Button(NSLocalizedString("Show in Finder", comment: "")) {
175+
if selectedProjectPaths.contains(projectPath) {
176+
self.selectedProjectPaths.forEach { projectPath in
177+
guard let url = URL(string: "file://\(projectPath)") else {
178+
return
179+
}
180+
NSWorkspace.shared.activateFileViewerSelecting([url])
181+
}
182+
} else {
183+
guard let url = URL(string: "file://\(projectPath)") else {
184+
return
185+
}
186+
NSWorkspace.shared.activateFileViewerSelecting([url])
187+
}
188+
}
189+
}
190+
}
191+
192+
private func contextMenuCopy(_ projectPath: String) -> some View {
193+
Group {
194+
Button(NSLocalizedString("Copy Path", comment: "")) {
195+
let pasteboard = NSPasteboard.general
196+
pasteboard.declareTypes([.string], owner: nil)
197+
pasteboard.setString(projectPath, forType: .string)
198+
}
199+
}
200+
}
201+
202+
private func contextMenuDelete(_ projectPath: String) -> some View {
203+
Group {
204+
Button(NSLocalizedString("Remove from Recent Projects", comment: "")) {
205+
if selectedProjectPaths.contains(projectPath) {
206+
self.selectedProjectPaths.forEach { projectPath in
207+
deleteFromRecent(item: projectPath)
208+
}
209+
} else {
210+
deleteFromRecent(item: projectPath)
211+
}
212+
}
213+
}
214+
}
215+
216+
// MARK: Keyboard Shortcuts
217+
218+
@ViewBuilder
219+
private func keyboardShortcutButtons(_ projectPath: String) -> some View {
220+
Button("") {
221+
deleteProject(projectPath: projectPath)
222+
}
223+
.buttonStyle(.borderless)
224+
.keyboardShortcut(.init(.delete))
225+
226+
Button("") {
227+
let pasteboard = NSPasteboard.general
228+
pasteboard.declareTypes([.string], owner: nil)
229+
pasteboard.setString(projectPath, forType: .string)
230+
}
231+
.buttonStyle(.borderless)
232+
.keyboardShortcut(mgr.named(with: "copy").keyboardShortcut)
233+
234+
Button("") {
235+
openProject(projectPath: projectPath)
214236
}
237+
.buttonStyle(.borderless)
238+
.keyboardShortcut(.defaultAction)
215239
}
216240
}

0 commit comments

Comments
 (0)