mirror of
https://github.com/yattee/yattee.git
synced 2026-08-06 15:21:29 +00:00
When an Invidious/Piped account is active, several views read the local SwiftData subscription store instead of the account, so counts contradicted each other (Home tile said 10 while the Channels list showed the server's 2): - Home Channels tile now uses the provider's count via new SubscriptionService.cachedSubscriptionCount (fetched once in the background when the server cache isn't populated yet) - Export footer and export content use the active account's list; export runs async with a spinner and surfaces fetch errors as a toast - CSV/OPML import routes through SubscriptionService.importSubscriptions, subscribing on the server for server accounts instead of silently writing to the invisible local store - ChannelView subscribe-state is corrected via the provider after the optimistic local-store read; unused *Sync write helpers removed - Server-account subscribe/unsubscribe/import now post subscriptionsDidChange so other views refresh - New "Delete Local Subscription Data" section in Subscriptions settings (visible with a server account) clears the local store and queues CloudKit deletions so iCloud doesn't restore it
71 lines
2.2 KiB
Swift
71 lines
2.2 KiB
Swift
//
|
|
// LocalSubscriptionProvider.swift
|
|
// Yattee
|
|
//
|
|
// Local subscription provider using SwiftData with iCloud sync.
|
|
// This is the default provider when using "Yattee (iCloud)" subscription account.
|
|
//
|
|
|
|
import Foundation
|
|
|
|
/// Local subscription provider that stores subscriptions in SwiftData.
|
|
/// Syncs with iCloud via CloudKitSyncEngine.
|
|
@MainActor
|
|
final class LocalSubscriptionProvider: SubscriptionProvider {
|
|
// MARK: - Properties
|
|
|
|
let accountType: SubscriptionAccountType = .local
|
|
private let dataManager: DataManager
|
|
|
|
// MARK: - Initialization
|
|
|
|
init(dataManager: DataManager) {
|
|
self.dataManager = dataManager
|
|
}
|
|
|
|
// MARK: - SubscriptionProvider
|
|
|
|
func fetchSubscriptions() async throws -> [Channel] {
|
|
// Convert Subscription models to Channel models
|
|
dataManager.subscriptions().map { subscription in
|
|
Channel(
|
|
id: ChannelID(source: subscription.contentSource, channelID: subscription.channelID),
|
|
name: subscription.name,
|
|
description: subscription.channelDescription,
|
|
subscriberCount: subscription.subscriberCount,
|
|
thumbnailURL: subscription.avatarURL,
|
|
bannerURL: subscription.bannerURL,
|
|
isVerified: subscription.isVerified
|
|
)
|
|
}
|
|
}
|
|
|
|
func subscribe(to channel: Channel) async throws {
|
|
// Check if already subscribed
|
|
if dataManager.isSubscribed(to: channel.id.channelID) {
|
|
throw SubscriptionProviderError.alreadySubscribed
|
|
}
|
|
dataManager.subscribe(to: channel)
|
|
}
|
|
|
|
func unsubscribe(from channelID: String) async throws {
|
|
// Check if subscribed
|
|
guard dataManager.isSubscribed(to: channelID) else {
|
|
throw SubscriptionProviderError.notSubscribed
|
|
}
|
|
dataManager.unsubscribe(from: channelID)
|
|
}
|
|
|
|
func isSubscribed(to channelID: String) async -> Bool {
|
|
dataManager.isSubscribed(to: channelID)
|
|
}
|
|
|
|
func refreshCache() async throws {
|
|
// Local provider doesn't need cache refresh - data is already local
|
|
}
|
|
|
|
var cachedSubscriptionCount: Int? {
|
|
dataManager.subscriptionCount
|
|
}
|
|
}
|