Skip to content

Commit 6685712

Browse files
committed
refactor(sidebar): type-safe favorite selection and drop AnyView from the favorites tree
1 parent 722cf59 commit 6685712

3 files changed

Lines changed: 198 additions & 150 deletions

File tree

TablePro/ViewModels/ConnectionSidebarState.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ internal final class ConnectionSidebarState {
2020

2121
let connectionId: UUID
2222

23-
var selectedFavoriteNodeId: String? {
23+
var selectedFavorite: FavoriteSelection? {
2424
didSet {
25-
guard oldValue != selectedFavoriteNodeId else { return }
25+
guard oldValue != selectedFavorite else { return }
2626
persistFavoriteSelection()
2727
}
2828
}
@@ -33,14 +33,14 @@ internal final class ConnectionSidebarState {
3333

3434
private init(connectionId: UUID) {
3535
self.connectionId = connectionId
36-
self.selectedFavoriteNodeId = UserDefaults.standard.string(
36+
self.selectedFavorite = UserDefaults.standard.string(
3737
forKey: "sidebar.selectedFavoriteNodeId.\(connectionId.uuidString)"
38-
)
38+
).flatMap(FavoriteSelection.init(rawValue:))
3939
}
4040

4141
private func persistFavoriteSelection() {
42-
if let selectedFavoriteNodeId {
43-
UserDefaults.standard.set(selectedFavoriteNodeId, forKey: favoriteSelectionKey)
42+
if let rawValue = selectedFavorite?.rawValue {
43+
UserDefaults.standard.set(rawValue, forKey: favoriteSelectionKey)
4444
} else {
4545
UserDefaults.standard.removeObject(forKey: favoriteSelectionKey)
4646
}

TablePro/ViewModels/FavoritesSidebarViewModel.swift

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,36 @@ internal struct FavoriteEditItem: Identifiable {
1313
let folderId: UUID?
1414
}
1515

16+
internal enum FavoriteSelection: Hashable {
17+
case table(schema: String?, name: String)
18+
case node(id: String)
19+
}
20+
21+
extension FavoriteSelection: RawRepresentable {
22+
private static let separator = "\u{1}"
23+
24+
init?(rawValue: String) {
25+
let parts = rawValue.components(separatedBy: Self.separator)
26+
switch parts.first {
27+
case "table" where parts.count == 3:
28+
self = .table(schema: parts[1].isEmpty ? nil : parts[1], name: parts[2])
29+
case "node" where parts.count >= 2:
30+
self = .node(id: parts.dropFirst().joined(separator: Self.separator))
31+
default:
32+
return nil
33+
}
34+
}
35+
36+
var rawValue: String {
37+
switch self {
38+
case .table(let schema, let name):
39+
return ["table", schema ?? "", name].joined(separator: Self.separator)
40+
case .node(let id):
41+
return ["node", id].joined(separator: Self.separator)
42+
}
43+
}
44+
}
45+
1646
internal struct FavoriteNode: Identifiable, Hashable {
1747
enum Content: Hashable {
1848
case folder(SQLFavoriteFolder)
@@ -353,20 +383,8 @@ internal final class FavoritesSidebarViewModel {
353383
}
354384
}
355385

356-
func favoriteForNodeId(_ id: String) -> SQLFavorite? {
357-
findNode(nodes, id: id, extract: \.asFavorite)
358-
}
359-
360-
func linkedFavoriteForNodeId(_ id: String) -> LinkedSQLFavorite? {
361-
findNode(nodes, id: id, extract: \.asLinkedFavorite)
362-
}
363-
364-
func folderForNodeId(_ id: String) -> SQLFavoriteFolder? {
365-
findNode(nodes, id: id, extract: \.asFolder)
366-
}
367-
368-
func linkedFolderForNodeId(_ id: String) -> LinkedSQLFolder? {
369-
findNode(nodes, id: id, extract: \.asLinkedFolder)
386+
func node(forId id: String) -> FavoriteNode? {
387+
findNode(nodes, id: id, extract: { $0 })
370388
}
371389

372390
private func findNode<T>(

0 commit comments

Comments
 (0)