Skip to content

Commit b8b0c60

Browse files
committed
add breadcrumb
1 parent 0195728 commit b8b0c60

File tree

2 files changed

+58
-92
lines changed

2 files changed

+58
-92
lines changed

Examples/SupaDrive/AppView.swift

+56-90
Original file line numberDiff line numberDiff line change
@@ -9,94 +9,57 @@ import CustomDump
99
import Supabase
1010
import SwiftUI
1111

12-
enum Item: Identifiable, Hashable {
13-
case folder(FileObject)
14-
case file(FileObject)
15-
16-
var id: String? {
17-
switch self {
18-
case let .file(file): file.id
19-
case let .folder(folder): folder.id
20-
}
21-
}
22-
23-
var name: String {
24-
switch self {
25-
case let .file(file): file.name
26-
case let .folder(folder): folder.name
27-
}
28-
}
29-
30-
var isFolder: Bool {
31-
if case .folder = self { return true }
32-
return false
33-
}
34-
35-
var isFile: Bool {
36-
if case .file = self { return true }
37-
return false
38-
}
39-
}
40-
41-
//
42-
// struct Folder: Identifiable, Hashable {
43-
// let id: String
44-
// let name: String
45-
// let items: [Item]
46-
// }
47-
//
48-
// struct File: Identifiable, Hashable {
49-
// let id: String
50-
// let name: String
51-
// }
52-
5312
struct AppView: View {
5413
@State var path: [String]
55-
@State var selectedItemPerPath: [String: Item] = [:]
14+
@State var selectedItemPerPath: [String: FileObject] = [:]
5615

5716
@State var reload = UUID()
5817

5918
var body: some View {
60-
ScrollView(.horizontal) {
61-
HStack {
62-
ForEach(path.indices, id: \.self) { pathIndex in
63-
PanelView(
64-
path: path[0 ... pathIndex].joined(separator: "/"),
65-
selectedItem: Binding(
66-
get: {
67-
selectedItemPerPath[path[pathIndex]]
68-
},
69-
set: { newValue in
70-
selectedItemPerPath[path[pathIndex]] = newValue
71-
72-
if case let .folder(folder) = newValue {
73-
path.replaceSubrange((pathIndex + 1)..., with: [folder.name])
74-
} else {
75-
path.replaceSubrange((pathIndex + 1)..., with: [])
19+
VStack(alignment: .leading, spacing: 0) {
20+
breadcrump
21+
22+
ScrollView(.horizontal) {
23+
HStack {
24+
ForEach(path.indices, id: \.self) { pathIndex in
25+
PanelView(
26+
path: path[0 ... pathIndex].joined(separator: "/"),
27+
selectedItem: Binding(
28+
get: {
29+
selectedItemPerPath[path[pathIndex]]
30+
},
31+
set: { newValue in
32+
selectedItemPerPath[path[pathIndex]] = newValue
33+
34+
if let newValue, let name = newValue.name, newValue.id == nil {
35+
path.replaceSubrange((pathIndex + 1)..., with: [name])
36+
} else {
37+
path.replaceSubrange((pathIndex + 1)..., with: [])
38+
}
7639
}
77-
}
40+
)
7841
)
79-
)
80-
.frame(width: 200)
42+
.frame(width: 200)
43+
}
8144
}
8245
}
8346
}
8447
.overlay(alignment: .trailing) {
8548
if
8649
let lastPath = path.last,
8750
let selectedItem = selectedItemPerPath[lastPath],
88-
case let .file(file) = selectedItem
51+
selectedItem.id != nil
8952
{
9053
Form {
91-
Text(file.name)
54+
Text(selectedItem.name ?? "")
9255
.font(.title2)
9356
Divider()
9457

95-
if let contentLenth = file.metadata?["contentLength"]?.intValue {
58+
if let contentLenth = selectedItem.metadata?["contentLength"]?.intValue {
9659
LabeledContent("Size", value: "\(contentLenth)")
9760
}
9861

99-
if let mimeType = file.metadata?["mimetype"]?.stringValue {
62+
if let mimeType = selectedItem.metadata?["mimetype"]?.stringValue {
10063
LabeledContent("MIME Type", value: mimeType)
10164
}
10265
}
@@ -107,29 +70,44 @@ struct AppView: View {
10770
.transition(.move(edge: .trailing))
10871
}
10972
}
110-
.animation(.default, value: path.last)
73+
.animation(.default, value: path)
74+
.animation(.default, value: selectedItemPerPath)
75+
}
76+
77+
var breadcrump: some View {
78+
HStack {
79+
ForEach(Array(zip(path.indices, path)), id: \.0) { idx, path in
80+
Button(path) {
81+
self.path.replaceSubrange((idx + 1)..., with: [])
82+
}
83+
.buttonStyle(.plain)
84+
85+
if idx != self.path.indices.last {
86+
Text(">")
87+
}
88+
}
89+
}
90+
.padding()
11191
}
11292
}
11393

11494
struct PanelView: View {
11595
var path: String
116-
@Binding var selectedItem: Item?
96+
@Binding var selectedItem: FileObject?
11797

11898
@State private var isDraggingOver = false
119-
@State private var items: [Item] = []
99+
@State private var items: [FileObject] = []
120100

121101
@State private var reload = UUID()
122102

123103
var body: some View {
124104
List {
125-
Section(path) {
126-
ForEach(items) { item in
127-
Button {
128-
selectedItem = item
129-
} label: {
130-
Text(item.name)
131-
.background(selectedItem == item ? Color.blue : Color.clear)
132-
}
105+
ForEach(items) { item in
106+
Button {
107+
selectedItem = item
108+
} label: {
109+
Text(item.name ?? "")
110+
.bold(selectedItem == item)
133111
}
134112
}
135113
.buttonStyle(.plain)
@@ -138,7 +116,7 @@ struct PanelView: View {
138116
do {
139117
let files = try await supabase.storage.from("main").list(path: path)
140118

141-
items = files.compactMap(Item.init)
119+
items = files.filter { $0.name?.hasPrefix(".") == false }
142120
} catch {
143121
dump(error)
144122
}
@@ -150,7 +128,7 @@ struct PanelView: View {
150128
return
151129
}
152130

153-
Task {
131+
Task { @MainActor in
154132
let path = url.lastPathComponent
155133
let file = try! Data(contentsOf: url)
156134
try! await supabase.storage.from("main")
@@ -179,18 +157,6 @@ struct PanelView: View {
179157
}
180158
}
181159

182-
extension Item {
183-
init?(file: FileObject) {
184-
if file.name.hasPrefix(".") { return nil }
185-
186-
if file.id == nil {
187-
self = .folder(file)
188-
} else {
189-
self = .file(file)
190-
}
191-
}
192-
}
193-
194160
extension FileObject {
195161
var metadataDump: String {
196162
var output = ""

Sources/Storage/FileObject.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ public struct FileObject: Identifiable, Hashable, Codable, Sendable {
55
public var name: String?
66
public var bucketId: String?
77
public var owner: String?
8-
public var id: UUID
8+
public var id: UUID?
99
public var updatedAt: Date?
1010
public var createdAt: Date?
1111
public var lastAccessedAt: Date?
@@ -15,7 +15,7 @@ public struct FileObject: Identifiable, Hashable, Codable, Sendable {
1515
name: String? = nil,
1616
bucketId: String? = nil,
1717
owner: String? = nil,
18-
id: UUID,
18+
id: UUID?,
1919
updatedAt: Date? = nil,
2020
createdAt: Date? = nil,
2121
lastAccessedAt: Date? = nil,

0 commit comments

Comments
 (0)