// // SavedDataManager.swift // Tusker // // Created by Shadowfacts on 12/19/19. // Copyright © 2019 Shadowfacts. All rights reserved. // import Foundation import Pachyderm class SavedDataManager: Codable { private(set) static var shared: SavedDataManager = load() private static var documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! private static var archiveURL = SavedDataManager.documentsDirectory.appendingPathComponent("saved_data").appendingPathExtension("plist") static func save() { DispatchQueue.global(qos: .utility).async { let encoder = PropertyListEncoder() let data = try? encoder.encode(shared) try? data?.write(to: archiveURL, options: .noFileProtection) } } static func load() -> SavedDataManager { let decoder = PropertyListDecoder() if let data = try? Data(contentsOf: archiveURL), let savedHashtagsManager = try? decoder.decode(Self.self, from: data) { return savedHashtagsManager } return SavedDataManager() } private init() {} private var savedHashtags: [String: [Hashtag]] = [:] { didSet { SavedDataManager.save() NotificationCenter.default.post(name: .savedHashtagsChanged, object: nil) } } private var savedInstances: [String: [URL]] = [:] { didSet { SavedDataManager.save() NotificationCenter.default.post(name: .savedInstancesChanged, object: nil) } } func sortedHashtags(for account: LocalData.UserAccountInfo) -> [Hashtag] { if let hashtags = savedHashtags[account.id] { return hashtags.sorted(by: { $0.name < $1.name }) } else { return [] } } func isSaved(hashtag: Hashtag, for account: LocalData.UserAccountInfo) -> Bool { return savedHashtags[account.id]?.contains(hashtag) ?? false } func add(hashtag: Hashtag, for account: LocalData.UserAccountInfo) { if isSaved(hashtag: hashtag, for: account) { return } if var saved = savedHashtags[account.id] { saved.append(hashtag) savedHashtags[account.id] = saved } else { savedHashtags[account.id] = [hashtag] } } func remove(hashtag: Hashtag, for account: LocalData.UserAccountInfo) { guard isSaved(hashtag: hashtag, for: account) else { return } if var saved = savedHashtags[account.id] { saved.removeAll(where: { $0.name == hashtag.name }) savedHashtags[account.id] = saved } } func savedInstances(for account: LocalData.UserAccountInfo) -> [URL] { return savedInstances[account.id] ?? [] } func isSaved(instance url: URL, for account: LocalData.UserAccountInfo) -> Bool { return savedInstances[account.id]?.contains(url) ?? false } func add(instance url: URL, for account: LocalData.UserAccountInfo) { if isSaved(instance: url, for: account) { return } if var saved = savedInstances[account.id] { saved.append(url) savedInstances[account.id] = saved } else { savedInstances[account.id] = [url] } } func remove(instance url: URL, for account: LocalData.UserAccountInfo) { guard isSaved(instance: url, for: account) else { return } if var saved = savedInstances[account.id] { saved.removeAll(where: { $0 == url }) savedInstances[account.id] = saved } } } extension Foundation.Notification.Name { static let savedHashtagsChanged = Notification.Name("savedHashtagsChanged") static let savedInstancesChanged = Notification.Name("savedInstancesChanged") }