Primera build enviada

This commit is contained in:
2026-01-19 14:40:43 +01:00
parent c6be398e5a
commit b03d35194f
36 changed files with 1641 additions and 561 deletions
@@ -36,6 +36,7 @@ class SourceDetailViewModel: ObservableObject {
private var cancellables = Set<AnyCancellable>()
private var isRefreshing = false
private var refreshQueued = false
private var refreshTask: Task<Void, Never>?
// MARK: - Initialization
@@ -97,15 +98,21 @@ class SourceDetailViewModel: ObservableObject {
guard !isRefreshing else { return }
isRefreshing = true
Task { [weak self] in
// Cancel any previous refresh task to avoid stale updates
refreshTask?.cancel()
refreshTask = Task { [weak self] in
guard let self else { return }
while self.refreshQueued {
while self.refreshQueued && !Task.isCancelled {
self.refreshQueued = false
// Fetch snapshots (filtered by freemium limits)
let allSnapshots = snapshotRepository.fetchSnapshots(for: source)
let filteredSnapshots = freemiumValidator.filterSnapshots(allSnapshots)
// Check for cancellation before updating UI
guard !Task.isCancelled else { break }
// Performance: Only update if data actually changed
let snapshotsChanged = filteredSnapshots.count != self.snapshots.count ||
filteredSnapshots.first?.date != self.snapshots.first?.date
@@ -139,6 +146,12 @@ class SourceDetailViewModel: ObservableObject {
}
}
/// Cancel any ongoing background tasks - call when view disappears
func cancelPendingTasks() {
refreshTask?.cancel()
refreshTask = nil
}
// MARK: - Snapshot Actions
func addSnapshot(date: Date, value: Decimal, contribution: Decimal?, notes: String?) {
@@ -288,21 +301,22 @@ class SourceDetailViewModel: ObservableObject {
}
var isHistoryLimited: Bool {
!freemiumValidator.isPremium && hiddenSnapshotCount > 0
!freemiumValidator.isPremium
}
var hiddenSnapshotCount: Int {
guard let limit = snapshotDisplayLimit else { return 0 }
return max(0, snapshots.count - min(limit, snapshots.count))
}
// For free users, count how many snapshots are hidden due to the 12-month limit
guard !freemiumValidator.isPremium else { return 0 }
var snapshotDisplayLimit: Int? {
freemiumValidator.isPremium ? nil : 10
// Get all snapshots without the date filter
let allSnapshots = snapshotRepository.fetchSnapshots(for: source)
return max(0, allSnapshots.count - snapshots.count)
}
var visibleSnapshots: [Snapshot] {
guard let limit = snapshotDisplayLimit else { return snapshots }
return Array(snapshots.prefix(limit))
// Premium users see all snapshots (already filtered by freemiumValidator in refreshData)
// Free users also see all their filtered snapshots (limited to last 12 months)
snapshots
}
private func isRelevantChange(_ notification: Notification) -> Bool {