diff options
| author | Christian Cleberg <[email protected]> | 2026-07-17 10:45:42 -0500 |
|---|---|---|
| committer | Christian Cleberg <[email protected]> | 2026-07-17 10:57:30 -0500 |
| commit | fbf2d9bf2cf50eb681afe18deac06a96c04004e6 (patch) | |
| tree | f337f6826c283d4246cdde824786bd18b6c770b3 /DomainDig/DomainDigUI.swift | |
| parent | 6e273c2676ce29cef057d117e4427e031886e743 (diff) | |
| download | domain-dig-fbf2d9bf2cf50eb681afe18deac06a96c04004e6.tar.gz domain-dig-fbf2d9bf2cf50eb681afe18deac06a96c04004e6.tar.bz2 domain-dig-fbf2d9bf2cf50eb681afe18deac06a96c04004e6.zip | |
v4.7.0: Add watchlist tags and saved filter views
- TrackedDomain.tags: [String] (backward-compatible custom decode), with
updateTags(_:for:) and a normalized/deduplicated write path.
- Tag editing in TrackedDomainDetailView (comma-separated field, chip display).
- Tag filter chips in WatchlistView (TagFilterChipRowView), integrated into
filteredTrackedDomains alongside the existing filter/search.
- Saved views: name + snapshot the current tag/filter/sort as a
WatchlistSavedView preset (UserDefaults-backed, not part of backup/restore),
with a management sheet to apply or delete presets.
Diffstat (limited to 'DomainDig/DomainDigUI.swift')
| -rw-r--r-- | DomainDig/DomainDigUI.swift | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/DomainDig/DomainDigUI.swift b/DomainDig/DomainDigUI.swift index 592d7a7..272c678 100644 --- a/DomainDig/DomainDigUI.swift +++ b/DomainDig/DomainDigUI.swift @@ -332,3 +332,57 @@ struct CollapsibleSectionView<HeaderTrailing: View, Content: View>: View { } } } + +/// A horizontally scrolling row of read-only tag chips, e.g. for a tracked +/// domain's detail view. +struct TagChipRowView: View { + let tags: [String] + + var body: some View { + ScrollView(.horizontal, showsIndicators: false) { + HStack(spacing: 8) { + ForEach(tags, id: \.self) { tag in + Text(tag) + .font(.caption) + .padding(.horizontal, 10) + .padding(.vertical, 5) + .background(Color(.systemGray5).opacity(0.6), in: Capsule()) + } + } + } + } +} + +/// A horizontally scrolling row of selectable tag chips used to filter a list, +/// with an "All" chip to clear the selection. +struct TagFilterChipRowView: View { + let tags: [String] + @Binding var selection: String? + + var body: some View { + ScrollView(.horizontal, showsIndicators: false) { + HStack(spacing: 8) { + filterChip(title: "All", isSelected: selection == nil) { + selection = nil + } + ForEach(tags, id: \.self) { tag in + filterChip(title: tag, isSelected: selection == tag) { + selection = (selection == tag) ? nil : tag + } + } + } + } + } + + private func filterChip(title: String, isSelected: Bool, action: @escaping () -> Void) -> some View { + Button(action: action) { + Text(title) + .font(.caption) + .padding(.horizontal, 10) + .padding(.vertical, 5) + .background(isSelected ? Color.cyan.opacity(0.3) : Color(.systemGray5).opacity(0.6), in: Capsule()) + .foregroundStyle(isSelected ? Color.cyan : Color.primary) + } + .buttonStyle(.plain) + } +} |
