weareopensource/Swift

View on GitHub
waosSwift/modules/tasks/reactors/TasksViewReactor.swift

Summary

Maintainability
A
0 mins
Test Coverage
/**
 * Dependencies
 */

import ReactorKit

enum TasksViewMode {
    case add
    case view(Tasks)
    case edit(Tasks)
}

/**
 * Reactor
 */

final class TasksViewReactor: Reactor {

    // MARK: Constants

    // user actions
    enum Action {
        // inputs
        case updateTitle(String)
        // default
        case done
    }

    // state changes
    enum Mutation {
        // inputs
        case updateTitle(String)
        // default
        case dismiss
        case error(CustomError)
    }

    // the current view state
    struct State {
        var task: Tasks
        var mode: TasksViewMode
        var isDismissed: Bool
        var error: DisplayError?

        init(task: Tasks, mode: TasksViewMode) {
            self.task = task
            self.mode = mode
            self.isDismissed = false
        }
    }

    // MARK: Properties

    let provider: AppServicesProviderType
    let mode: TasksViewMode
    let initialState: State

    // MARK: Initialization

    init(provider: AppServicesProviderType, mode: TasksViewMode) {
        self.provider = provider
        self.mode = mode

        switch mode {
        case .add:
            self.initialState = State(task: Tasks(), mode: mode)
        case .view(let task):
            self.initialState = State(task: task, mode: mode)
        case .edit(let task):
            self.initialState = State(task: task, mode: mode)
        }
    }

    // MARK: Action -> Mutation (mutate() receives an Action and generates an Observable<Mutation>)

    func mutate(action: Action) -> Observable<Mutation> {
        switch action {
        // updateTitle
        case let .updateTitle(title):
            return .just(.updateTitle(title))
        // done
        case .done:
            switch mode {
            case .add:
                return self.provider.tasksService
                    .create(self.currentState.task)
                    .map { result in
                        switch result {
                        case .success: return .dismiss
                        case let .error(err): return .error(err)
                        }
                    }
            case .view:
                return .just(.dismiss)
            case .edit:
                return self.provider.tasksService
                    .update(self.currentState.task)
                    .map { result in
                        switch result {
                        case .success: return .dismiss
                        case let .error(err): return .error(err)
                        }
                    }
            }
        }
    }

    // MARK: Mutation -> State (reduce() generates a new State from a previous State and a Mutation)

    func reduce(state: State, mutation: Mutation) -> State {
        var state = state
        switch mutation {
        // update title
        case let .updateTitle(title):
            state.task.title = title
        // dissmiss
        case .dismiss:
            log.verbose("♻️ Mutation -> State : dismiss")
            state.isDismissed = true
        // error
        case let .error(error):
            log.verbose("♻️ Mutation -> State : error \(error)")
            let _error: DisplayError = getDisplayError(error, self.provider.preferencesService.isLogged)
            self.provider.preferencesService.isLogged = _error.code == 401 ? false : true
            state.error = _error
        }
        return state
    }
}