// // UserDefaultsStore.swift // Feels (iOS) // // Created by Trey Tartt on 1/22/22. // import Foundation enum VotingLayoutStyle: Int, CaseIterable { case horizontal = 0 // Current: 5 buttons in a row case cards = 1 // Larger tappable cards with labels case radial = 2 // Semi-circle/wheel arrangement case stacked = 3 // Full-width vertical list var displayName: String { switch self { case .horizontal: return "Horizontal" case .cards: return "Cards" case .radial: return "Radial" case .stacked: return "Stacked" } } } class UserDefaultsStore { enum Keys: String { case savedOnboardingData case needsOnboarding case useCloudKit case deleteEnable case mainViewTopHeaderIndex case theme case moodImages case moodTint case personalityPack case customWidget case customMoodTint case customMoodTintUpdateNumber case textColor case showNSFW case shape case daysFilter case firstLaunchDate case hasActiveSubscription case lastVotedDate case votingLayoutStyle case contentViewCurrentSelectedHeaderViewBackDays case contentViewHeaderTag case contentViewHeaderTagViewOneViewType case contentViewHeaderTagViewTwoViewType case currentSelectedHeaderViewViewType } static func getOnboarding() -> OnboardingData { if let data = GroupUserDefaults.groupDefaults.object(forKey: UserDefaultsStore.Keys.savedOnboardingData.rawValue) as? Data, let model = try? JSONDecoder().decode(OnboardingData.self, from: data) { return model } else { return OnboardingData() } } @discardableResult static func saveOnboarding(onboardingData: OnboardingData) -> OnboardingData { do { let data = try JSONEncoder().encode(onboardingData) GroupUserDefaults.groupDefaults.set(data, forKey: UserDefaultsStore.Keys.savedOnboardingData.rawValue) } catch { print("Error saving onboarding: \(error)") } return UserDefaultsStore.getOnboarding() } static func moodMoodImagable() -> MoodImagable.Type { if let data = GroupUserDefaults.groupDefaults.object(forKey: UserDefaultsStore.Keys.moodImages.rawValue) as? Int, let model = MoodImages.init(rawValue: data) { return model.moodImages } else { return MoodImages.FontAwesome.moodImages } } static func moodTintable() -> MoodTintable.Type { if let data = GroupUserDefaults.groupDefaults.object(forKey: UserDefaultsStore.Keys.moodTint.rawValue) as? Int, let model = MoodTints.init(rawValue: data) { return model.moodTints } else { return MoodTints.Default.moodTints } } static func personalityPackable() -> PersonalityPack { if let data = GroupUserDefaults.groupDefaults.object(forKey: UserDefaultsStore.Keys.personalityPack.rawValue) as? Int, let model = PersonalityPack.init(rawValue: data) { return model } else { return PersonalityPack.Default } } static func theme() -> Theme { if let data = GroupUserDefaults.groupDefaults.object(forKey: UserDefaultsStore.Keys.theme.rawValue) as? Int, let model = Theme.init(rawValue: data) { return model } else { return Theme.system } } static func getCustomWidgets() -> [CustomWidgetModel] { if let data = GroupUserDefaults.groupDefaults.object(forKey: UserDefaultsStore.Keys.customWidget.rawValue) as? Data, let model = try? JSONDecoder().decode([CustomWidgetModel].self, from: data) { return model } else { GroupUserDefaults.groupDefaults.removeObject(forKey: UserDefaultsStore.Keys.customWidget.rawValue) let widget = CustomWidgetModel.randomWidget widget.isSaved = true let widgets = [widget] guard let data = try? JSONEncoder().encode(widgets) else { return widgets } GroupUserDefaults.groupDefaults.set(data, forKey: UserDefaultsStore.Keys.customWidget.rawValue) if let savedData = GroupUserDefaults.groupDefaults.object(forKey: UserDefaultsStore.Keys.customWidget.rawValue) as? Data, let models = try? JSONDecoder().decode([CustomWidgetModel].self, from: savedData) { return models.sorted { $0.createdDate < $1.createdDate } } else { return widgets } } } @discardableResult static func saveCustomWidget(widgetModel: CustomWidgetModel, inUse: Bool) -> [CustomWidgetModel] { do { var existingWidgets = getCustomWidgets() if let exisitingWidget = existingWidgets.firstIndex(where: { $0.uuid == widgetModel.uuid }) { existingWidgets.remove(at: exisitingWidget) // give it differnet uuid so the view updates widgetModel.uuid = UUID().uuidString } if inUse { existingWidgets.forEach({ $0.inUse = false }) widgetModel.inUse = true } existingWidgets.append(widgetModel) existingWidgets.forEach({ $0.isSaved = true }) let data = try JSONEncoder().encode(existingWidgets) GroupUserDefaults.groupDefaults.set(data, forKey: UserDefaultsStore.Keys.customWidget.rawValue) } catch { print("Error saving custom widget: \(error)") } return UserDefaultsStore.getCustomWidgets() } @discardableResult static func deleteCustomWidget(withUUID uuid: String) -> [CustomWidgetModel] { do { var existingWidgets = getCustomWidgets() if let exisitingWidget = existingWidgets.firstIndex(where: { $0.uuid == uuid }) { existingWidgets.remove(at: exisitingWidget) } if existingWidgets.count == 0 { let widget = CustomWidgetModel.randomWidget widget.isSaved = true widget.inUse = true existingWidgets.append(widget) } if existingWidgets.first(where: { $0.inUse == true }) == nil { existingWidgets.first?.inUse = true } let data = try JSONEncoder().encode(existingWidgets) GroupUserDefaults.groupDefaults.set(data, forKey: UserDefaultsStore.Keys.customWidget.rawValue) } catch { print("Error deleting custom widget: \(error)") } return UserDefaultsStore.getCustomWidgets() } static func getCustomMoodTint() -> SavedMoodTint { if let data = GroupUserDefaults.groupDefaults.object(forKey: UserDefaultsStore.Keys.customMoodTint.rawValue) as? Data{ do { let model = try JSONDecoder().decode(SavedMoodTint.self, from: data) return model } catch { print(error) } } return SavedMoodTint() } static func getCustomBGShape() -> BGShape { if let data = GroupUserDefaults.groupDefaults.object(forKey: UserDefaultsStore.Keys.shape.rawValue) as? Int, let model = BGShape.init(rawValue: data) { return model } else { return BGShape.circle } } @discardableResult static func saveCustomMoodTint(customTint: SavedMoodTint) -> SavedMoodTint { do { let data = try JSONEncoder().encode(customTint) GroupUserDefaults.groupDefaults.set(data, forKey: UserDefaultsStore.Keys.customMoodTint.rawValue) } catch { print("Error saving custom mood tint: \(error)") } return UserDefaultsStore.getCustomMoodTint() } @discardableResult static func saveDaysFilter(days: [Int]) -> [Int] { GroupUserDefaults.groupDefaults.set(days, forKey: UserDefaultsStore.Keys.daysFilter.rawValue) return UserDefaultsStore.getDaysFilter() } static func getDaysFilter() -> [Int] { if let data = GroupUserDefaults.groupDefaults.object(forKey: UserDefaultsStore.Keys.daysFilter.rawValue) as? [Int] { return data } else { return [1,2,3,4,5,6,7] } } }