|
|
package nova.monadic_sfx.ui.components.todo
import com.softwaremill.quicklens._ import io.circe.generic.JsonCodec import io.odin.Logger import monix.bio.Task import nova.monadic_sfx.util.reactive.Middlewares.actionLoggerMiddleware import nova.monadic_sfx.util.reactive.Reducer import nova.monadic_sfx.util.reactive.Store
case class Todo(id: Int, content: String)
object TodoListStore {
@JsonCodec sealed trait Action case object Init extends Action case class Add(content: String) extends Action case class Edit(id: Int, content: String) extends Action case class Delete(id: Int) extends Action
private case class InternalAdd(content: String) extends Action private case object End extends Action
case class State(todos: Vector[Todo], counter: Int)
def reducer(logger: Logger[Task])( state: State, action: Action ): (State, Option[Task[Action]]) = action match { case Init => (state, None) case Add(content) => val nextAction = Some(for { // _ <- logger.debug(s"Received $content")
res <- Task.pure(InternalAdd(content)) } yield res) (state, nextAction) case Edit(_id, content) => val condition: Todo => Boolean = _.id == _id val nextState = state .modify(_.todos.eachWhere(condition)) .using(_.copy(content = content)) (nextState, None) case Delete(id) => (state.copy(state.todos.filterNot(_.id == id)), None)
case InternalAdd(content) => val nextState = state.copy( todos = state.todos :+ Todo(state.counter, content), counter = state.counter + 1 ) (nextState, Some(logger.debug(s"Received $content") >> Task.pure(End))) case End => (state, None) }
def apply(logger: Logger[Task]) = Task.deferAction(implicit s => for { logMware <- actionLoggerMiddleware[Action, State](logger, "TodoStore") store <- Store .createL[Action, State]( Init, State(Vector.empty[Todo], 0), Reducer.withOptionalEffects(reducer(logger) _), Seq( // actionLoggerMiddleware(logger, "TodoStore2")
logMware ) ) } yield (store) ) }
// Task.deferAction(implicit s =>
// Store
// .createJsonL[Action, State](
// Init,
// State(Vector.empty[Todo], 0),
// Reducer.withOptionalEffects(reducer(logger) _),
// "TodoStore",
// logger
// // Seq(
// // actionLoggerMiddleware(logger, "TodoStore")
// // // actionLoggerMiddleware(logger, "TodoStore2")
// // )
// )
// )
|