import Defaults import Foundation struct FavoritesModel { static let shared = Self() @Default(.showFavoritesInHome) var showFavoritesInHome @Default(.favorites) var all @Default(.widgetsSettings) var widgetsSettings var isEnabled: Bool { showFavoritesInHome } func contains(_ item: FavoriteItem) -> Bool { all.contains { $0 == item } } func toggle(_ item: FavoriteItem) { if contains(item) { remove(item) } else { add(item) } } func add(_ item: FavoriteItem) { if contains(item) { return } all.append(item) } func remove(_ item: FavoriteItem) { if let index = all.firstIndex(where: { $0 == item }) { all.remove(at: index) } } func canMoveUp(_ item: FavoriteItem) -> Bool { if let index = all.firstIndex(where: { $0 == item }) { return index > all.startIndex } return false } func canMoveDown(_ item: FavoriteItem) -> Bool { if let index = all.firstIndex(where: { $0 == item }) { return index < all.endIndex - 1 } return false } func moveUp(_ item: FavoriteItem) { guard canMoveUp(item) else { return } if let from = all.firstIndex(where: { $0 == item }) { all.move( fromOffsets: IndexSet(integer: from), toOffset: from - 1 ) } } func moveDown(_ item: FavoriteItem) { guard canMoveDown(item) else { return } if let from = all.firstIndex(where: { $0 == item }) { all.move( fromOffsets: IndexSet(integer: from), toOffset: from + 2 ) } } func addableItems() -> [FavoriteItem] { let allItems = [ FavoriteItem(section: .subscriptions), FavoriteItem(section: .popular), FavoriteItem(section: .history) ] return allItems.filter { item in !all.contains { $0.section == item.section } } } func listingStyle(_ item: FavoriteItem) -> WidgetListingStyle { widgetSettings(item).listingStyle } func limit(_ item: FavoriteItem) -> Int { min(WidgetSettings.maxLimit(listingStyle(item)), widgetSettings(item).limit) } func setListingStyle(_ style: WidgetListingStyle, _ item: FavoriteItem) { if let index = widgetsSettings.firstIndex(where: { $0.id == item.widgetSettingsKey }) { var settings = widgetsSettings[index] settings.listingStyle = style widgetsSettings[index] = settings } else { let settings = WidgetSettings(id: item.widgetSettingsKey, listingStyle: style) widgetsSettings.append(settings) } } func setLimit(_ limit: Int, _ item: FavoriteItem) { if let index = widgetsSettings.firstIndex(where: { $0.id == item.widgetSettingsKey }) { var settings = widgetsSettings[index] let limit = min(max(1, limit), WidgetSettings.maxLimit(settings.listingStyle)) settings.limit = limit widgetsSettings[index] = settings } else { var settings = WidgetSettings(id: item.widgetSettingsKey, limit: limit) let limit = min(max(1, limit), WidgetSettings.maxLimit(settings.listingStyle)) settings.limit = limit widgetsSettings.append(settings) } } func widgetSettings(_ item: FavoriteItem) -> WidgetSettings { widgetsSettings.first { $0.id == item.widgetSettingsKey } ?? WidgetSettings(id: item.widgetSettingsKey) } func updateWidgetSettings(_ settings: WidgetSettings) { if let index = widgetsSettings.firstIndex(where: { $0.id == settings.id }) { widgetsSettings[index] = settings } else { widgetsSettings.append(settings) } } }