- Replace Copper accent with Plum (light #6B4577 / dark #A67FB0) across the main
app and AutoFill extension.
- Replace the padlock app icon with a vault-door design (ring, hub, locking
handle) in Plum, plus all macOS sizes.
- Add an AppIconImage asset (separate from the AppIcon icon-set, which SwiftUI
can't reference directly at runtime) and show it on the unlock screen instead
of a generic SF Symbol.
- GroupFilterView: move "Clear Filter" out of the list and into a leading
toolbar button ("Clear", disabled when no filter is active), mirroring the
trailing "Done" button.
55 lines
1.6 KiB
Swift
55 lines
1.6 KiB
Swift
import SwiftUI
|
|
import KeeVaultCore
|
|
|
|
struct GroupFilterView: View {
|
|
@ObservedObject var vm: GroupFilterViewModel
|
|
let rootGroup: KeeVaultCore.Group
|
|
|
|
var body: some View {
|
|
List {
|
|
GroupFilterNode(group: rootGroup, vm: vm)
|
|
}
|
|
.scrollContentBackground(.hidden)
|
|
.background(Color("VaultBackground"))
|
|
.navigationTitle("Groups")
|
|
.toolbar {
|
|
ToolbarItem(placement: .cancellationAction) {
|
|
Button("Clear", action: vm.clear)
|
|
.disabled(vm.selectedGroupIds.isEmpty)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private struct GroupFilterNode: View {
|
|
let group: KeeVaultCore.Group
|
|
@ObservedObject var vm: GroupFilterViewModel
|
|
var depth: Int = 0
|
|
|
|
var body: some View {
|
|
// A plain SwiftUI.Group (not a container view) flattens its children into
|
|
// separate List rows, so the whole subtree renders always-expanded --
|
|
// no DisclosureGroup, no tap-to-reveal -- active filters are visible at a glance.
|
|
SwiftUI.Group {
|
|
row
|
|
ForEach(group.subgroups) { sub in
|
|
GroupFilterNode(group: sub, vm: vm, depth: depth + 1)
|
|
}
|
|
}
|
|
}
|
|
|
|
private var row: some View {
|
|
Button {
|
|
vm.toggle(group)
|
|
} label: {
|
|
HStack {
|
|
Image(systemName: vm.isSelected(group) ? "checkmark.circle.fill" : "circle")
|
|
.foregroundStyle(vm.isSelected(group) ? Color.accentColor : Color.secondary)
|
|
Label(group.name, systemImage: "folder")
|
|
}
|
|
}
|
|
.buttonStyle(.plain)
|
|
.padding(.leading, CGFloat(depth) * 16)
|
|
}
|
|
}
|