// // FactsFeature.swift // Meow // import Foundation import Core import CatFactsKit import ComposableArchitecture /// Handles the logic for fetching and displaying a `List` of cat facts from a remote API. @Reducer public struct FactsFeature { @ObservationIgnored @Dependency(\.clientFactory) var clientFactory @ObservableState public struct State { public var baseURL: URL public var mode: Mode = .notLoaded public init(baseURL: URL = URL(string: "https://invalid.barf")!, mode: Mode = .notLoaded) { self.baseURL = baseURL } } public enum Mode { case notLoaded case loading case loaded(facts: [String]) case error(Error) } public enum Action { case viewAppeared case pulledToRefresh case fetchNeeded case receivedFacts([String]) case receivedError(Error) } // MARK: - Public functionality public init() { } public var body: some ReducerOf { Reduce { state, action in switch action { case .viewAppeared: switch state.mode { case .loaded: return .none default: state.mode = .loading return .send(.fetchNeeded) } case .pulledToRefresh: return .send(.fetchNeeded) case .fetchNeeded: let client = clientFactory.createClient(baseURL: state.baseURL) return .run { send in do { let results = try await client.getFacts(count: 5) await send(.receivedFacts(results)) } catch { await send(.receivedError(error)) } } case let .receivedFacts(facts): state.mode = .loaded(facts: facts) return .none case let .receivedError(error): state.mode = .error(error) return .none } } } }