Skip to content

Commit 5b25946

Browse files
author
Luke
authored
Merge branch 'main' into main
2 parents ffa51e8 + add8b92 commit 5b25946

8 files changed

Lines changed: 144 additions & 1 deletion

File tree

CodeEdit.xcodeproj/project.pbxproj

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
04540D6127DD08C300E91B77 /* CodeFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 348313FB27DC8C070016D42C /* CodeFile.swift */; };
2020
04660F6427E3ACAF00477777 /* Appearances.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04660F6327E3ACAF00477777 /* Appearances.swift */; };
2121
04660F6627E3ACEF00477777 /* ReopenBehavior.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04660F6527E3ACEF00477777 /* ReopenBehavior.swift */; };
22+
286620A527E4AB6900E18C2B /* BreadcrumbsComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 286620A427E4AB6900E18C2B /* BreadcrumbsComponent.swift */; };
23+
2875A46D27E3BE5B007805F8 /* BreadcrumbsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2875A46C27E3BE5B007805F8 /* BreadcrumbsView.swift */; };
2224
287776E727E3413200D46668 /* SideBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 287776E627E3413200D46668 /* SideBar.swift */; };
2325
287776E927E34BC700D46668 /* TabBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 287776E827E34BC700D46668 /* TabBar.swift */; };
2426
287776ED27E350D800D46668 /* SideBarItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 287776EC27E350D800D46668 /* SideBarItem.swift */; };
@@ -65,6 +67,8 @@
6567
0468438427DC76E200F8E88E /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
6668
04F2BF0E27DBB28E0024EAB1 /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = "<group>"; };
6769
04F2BF1127DBB3C10024EAB1 /* GeneralSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeneralSettingsView.swift; sourceTree = "<group>"; };
70+
286620A427E4AB6900E18C2B /* BreadcrumbsComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BreadcrumbsComponent.swift; sourceTree = "<group>"; };
71+
2875A46C27E3BE5B007805F8 /* BreadcrumbsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BreadcrumbsView.swift; sourceTree = "<group>"; };
6872
287776E627E3413200D46668 /* SideBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SideBar.swift; sourceTree = "<group>"; };
6973
287776E827E34BC700D46668 /* TabBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBar.swift; sourceTree = "<group>"; };
7074
287776EC27E350D800D46668 /* SideBarItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SideBarItem.swift; sourceTree = "<group>"; };
@@ -151,6 +155,15 @@
151155
path = Settings;
152156
sourceTree = "<group>";
153157
};
158+
2875A46E27E3BE63007805F8 /* Breadcrumbs */ = {
159+
isa = PBXGroup;
160+
children = (
161+
2875A46C27E3BE5B007805F8 /* BreadcrumbsView.swift */,
162+
286620A427E4AB6900E18C2B /* BreadcrumbsComponent.swift */,
163+
);
164+
path = Breadcrumbs;
165+
sourceTree = "<group>";
166+
};
154167
287776EA27E350A100D46668 /* SideBar */ = {
155168
isa = PBXGroup;
156169
children = (
@@ -220,6 +233,7 @@
220233
043C321227E31FE8006AE443 /* Documents */,
221234
0468438427DC76E200F8E88E /* AppDelegate.swift */,
222235
B658FB3127DA9E0F00EA4DBD /* WorkspaceView.swift */,
236+
2875A46E27E3BE63007805F8 /* Breadcrumbs */,
223237
287776EA27E350A100D46668 /* SideBar */,
224238
287776EB27E350BA00D46668 /* TabBar */,
225239
345F667327DF6BCC0069BD69 /* Rows */,
@@ -389,6 +403,7 @@
389403
buildActionMask = 2147483647;
390404
files = (
391405
2B7A583527E4BA0100D25D4E /* AppDelegate.swift in Sources */,
406+
2875A46D27E3BE5B007805F8 /* BreadcrumbsView.swift in Sources */,
392407
04540D5B27DD08C300E91B77 /* SettingsView.swift in Sources */,
393408
04540D5C27DD08C300E91B77 /* GeneralSettingsView.swift in Sources */,
394409
043C321427E31FF6006AE443 /* CodeEditDocumentController.swift in Sources */,
@@ -398,6 +413,7 @@
398413
34EE19BE27E0469C00F152CE /* BlurView.swift in Sources */,
399414
D7211D4327E066CE008F2ED7 /* Localized+Ex.swift in Sources */,
400415
287776E927E34BC700D46668 /* TabBar.swift in Sources */,
416+
286620A527E4AB6900E18C2B /* BreadcrumbsComponent.swift in Sources */,
401417
287776EF27E3515300D46668 /* TabBarItem.swift in Sources */,
402418
287776E727E3413200D46668 /* SideBar.swift in Sources */,
403419
287776ED27E350D800D46668 /* SideBarItem.swift in Sources */,
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
//
2+
// BreadcrumbsComponent.swift
3+
// CodeEdit
4+
//
5+
// Created by Lukas Pistrol on 18.03.22.
6+
//
7+
8+
import SwiftUI
9+
10+
struct BreadcrumbsComponent: View {
11+
12+
private let title: String
13+
private let image: String
14+
private let color: Color
15+
16+
init(_ title: String, systemImage image: String, color: Color = .secondary) {
17+
self.title = title
18+
self.image = image
19+
self.color = color
20+
}
21+
22+
var body: some View {
23+
HStack {
24+
Image(systemName: image)
25+
.resizable()
26+
.aspectRatio(contentMode: .fit)
27+
.frame(width: 12)
28+
.foregroundStyle(color)
29+
Text(title)
30+
.foregroundStyle(.primary)
31+
.font(.system(size: 11))
32+
}
33+
}
34+
}
35+
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
//
2+
// BreadcrumbsView.swift
3+
// CodeEdit
4+
//
5+
// Created by Lukas Pistrol on 17.03.22.
6+
//
7+
8+
import SwiftUI
9+
import WorkspaceClient
10+
11+
struct BreadcrumbsView: View {
12+
13+
@ObservedObject var workspace: WorkspaceDocument
14+
let file: WorkspaceClient.FileItem
15+
16+
@State private var projectName: String = ""
17+
@State private var folders: [String] = []
18+
@State private var fileName: String = ""
19+
@State private var fileImage: String = "doc"
20+
21+
init(_ file: WorkspaceClient.FileItem, workspace: WorkspaceDocument) {
22+
self.file = file
23+
self.workspace = workspace
24+
}
25+
26+
var body: some View {
27+
ZStack(alignment: .leading) {
28+
Rectangle()
29+
.foregroundStyle(Color(nsColor: .controlBackgroundColor))
30+
HStack {
31+
BreadcrumbsComponent(projectName, systemImage: "square.dashed.inset.filled", color: .accentColor)
32+
chevron
33+
ForEach(folders, id:\.self) { folder in
34+
BreadcrumbsComponent(folder, systemImage: "folder.fill")
35+
chevron
36+
}
37+
BreadcrumbsComponent(fileName, systemImage: fileImage, color: .accentColor)
38+
}
39+
.padding(.leading, 12)
40+
}
41+
.frame(height: 29)
42+
.overlay(alignment: .bottom) {
43+
Divider()
44+
}
45+
.onAppear {
46+
fileInfo()
47+
}
48+
}
49+
50+
private var chevron: some View {
51+
Image(systemName: "chevron.compact.right")
52+
.foregroundStyle(.secondary)
53+
.imageScale(.large)
54+
}
55+
56+
private func fileInfo() {
57+
58+
guard let projName = workspace.folderURL?.lastPathComponent,
59+
var components = file.url.pathComponents.split(separator: projName).last else { return }
60+
components.removeLast()
61+
62+
self.projectName = projName
63+
self.folders = Array(components)
64+
self.fileName = file.fileName
65+
self.fileImage = file.systemImage
66+
}
67+
68+
}
69+
70+
struct BreadcrumbsView_Previews: PreviewProvider {
71+
static var previews: some View {
72+
BreadcrumbsView(.init(url: .init(fileURLWithPath: "", isDirectory: false)), workspace: .init())
73+
.previewLayout(.fixed(width: 500, height: 29))
74+
.preferredColorScheme(.dark)
75+
76+
BreadcrumbsView(.init(url: .init(fileURLWithPath: "", isDirectory: false)), workspace: .init())
77+
.previewLayout(.fixed(width: 500, height: 29))
78+
.preferredColorScheme(.light)
79+
}
80+
}

CodeEdit/Documents/WorkspaceDocument.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ class WorkspaceDocument: NSDocument, ObservableObject, NSToolbarDelegate {
2020
@Published var sortFoldersOnTop: Bool = true
2121
@Published var fileItems: [WorkspaceClient.FileItem] = []
2222
var openedCodeFiles: [WorkspaceClient.FileItem : CodeFile] = [:]
23+
var folderURL: URL?
2324
private var cancellable: AnyCancellable?
2425

2526
deinit {
@@ -90,6 +91,7 @@ class WorkspaceDocument: NSDocument, ObservableObject, NSToolbarDelegate {
9091
}
9192

9293
override func read(from url: URL, ofType typeName: String) throws {
94+
self.folderURL = url
9395
self.workspaceClient = try .default(
9496
fileManager: .default,
9597
folderURL: url,

CodeEdit/SideBar/SideBarItem.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,10 @@ struct SideBarItem: View {
2929
NavigationLink(tag: item.id, selection: $workspace.selectedId) {
3030
WorkspaceEditorView(workspace: workspace, item: item, windowController: windowController)
3131
.safeAreaInset(edge: .top) {
32-
TabBar(windowController: windowController, workspace: workspace)
32+
VStack(spacing: 0) {
33+
TabBar(windowController: windowController, workspace: workspace)
34+
BreadcrumbsView(item, workspace: workspace)
35+
}
3336
}
3437
} label: {
3538
Label(item.url.lastPathComponent, systemImage: item.systemImage)

CodeEditModules/Modules/WorkspaceClient/src/Interface.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,19 @@ import Combine
99
import Foundation
1010

1111
public struct WorkspaceClient {
12+
13+
public var folderURL: () -> URL?
14+
1215
public var getFiles: AnyPublisher<[FileItem], Never>
1316

1417
public var getFileItem: (_ id: String) throws -> FileItem
1518

1619
public init(
20+
folderURL: @escaping () -> URL?,
1721
getFiles: AnyPublisher<[FileItem], Never>,
1822
getFileItem: @escaping (_ id: String) throws -> FileItem
1923
) {
24+
self.folderURL = folderURL
2025
self.getFiles = getFiles
2126
self.getFileItem = getFileItem
2227
}

CodeEditModules/Modules/WorkspaceClient/src/Live.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ public extension WorkspaceClient {
8282
}
8383

8484
return Self(
85+
folderURL: { folderURL },
8586
getFiles: subject
8687
.handleEvents(receiveSubscription: { _ in
8788
startListeningToDirectory()

CodeEditModules/Modules/WorkspaceClient/src/Mocks.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import Foundation
1010

1111
public extension WorkspaceClient {
1212
static var empty = Self(
13+
folderURL: { nil },
1314
getFiles: CurrentValueSubject<[FileItem], Never>([]).eraseToAnyPublisher(),
1415
getFileItem: { _ in throw WorkspaceClientError.fileNotExist }
1516
)

0 commit comments

Comments
 (0)