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/Models.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/Models.swift')
| -rw-r--r-- | DomainDig/Models.swift | 34 |
1 files changed, 31 insertions, 3 deletions
diff --git a/DomainDig/Models.swift b/DomainDig/Models.swift index d14ff4a..b86fc07 100644 --- a/DomainDig/Models.swift +++ b/DomainDig/Models.swift @@ -882,7 +882,7 @@ struct TimelineSection: Identifiable, Equatable { let entries: [SnapshotSummary] } -enum WatchlistFilterOption: String, CaseIterable, Identifiable { +enum WatchlistFilterOption: String, CaseIterable, Identifiable, Codable { case all case pinnedOnly case changedOnly @@ -901,7 +901,7 @@ enum WatchlistFilterOption: String, CaseIterable, Identifiable { } } -enum WatchlistSortOption: String, CaseIterable, Identifiable { +enum WatchlistSortOption: String, CaseIterable, Identifiable, Codable { case pinned case recentlyUpdated case alphabetical @@ -920,6 +920,30 @@ enum WatchlistSortOption: String, CaseIterable, Identifiable { } } +/// A named watchlist filter preset (tag, filter, sort) the user can save and +/// reapply. Stored locally in UserDefaults; not included in backup/restore. +struct WatchlistSavedView: Codable, Identifiable, Equatable { + let id: UUID + var name: String + var tag: String? + var filter: WatchlistFilterOption + var sort: WatchlistSortOption + + init( + id: UUID = UUID(), + name: String, + tag: String?, + filter: WatchlistFilterOption, + sort: WatchlistSortOption + ) { + self.id = id + self.name = name + self.tag = tag + self.filter = filter + self.sort = sort + } +} + enum PortfolioFilterOption: String, CaseIterable, Identifiable { case all case healthy @@ -1258,6 +1282,7 @@ struct TrackedDomain: Codable, Identifiable, Equatable { var monitoringState: MonitoringState var pendingMonitoringAlerts: [MonitoringPendingAlert] var collaboration: CollaborationMetadata? + var tags: [String] init( id: UUID = UUID(), @@ -1277,7 +1302,8 @@ struct TrackedDomain: Codable, Identifiable, Equatable { lastAlertAt: Date? = nil, monitoringState: MonitoringState = MonitoringState(), pendingMonitoringAlerts: [MonitoringPendingAlert] = [], - collaboration: CollaborationMetadata? = nil + collaboration: CollaborationMetadata? = nil, + tags: [String] = [] ) { self.id = id self.domain = domain @@ -1297,6 +1323,7 @@ struct TrackedDomain: Codable, Identifiable, Equatable { self.monitoringState = monitoringState self.pendingMonitoringAlerts = pendingMonitoringAlerts self.collaboration = collaboration + self.tags = tags } init(from decoder: Decoder) throws { @@ -1319,6 +1346,7 @@ struct TrackedDomain: Codable, Identifiable, Equatable { monitoringState = try container.decodeIfPresent(MonitoringState.self, forKey: .monitoringState) ?? MonitoringState() pendingMonitoringAlerts = try container.decodeIfPresent([MonitoringPendingAlert].self, forKey: .pendingMonitoringAlerts) ?? [] collaboration = try container.decodeIfPresent(CollaborationMetadata.self, forKey: .collaboration) + tags = try container.decodeIfPresent([String].self, forKey: .tags) ?? [] } } |
