You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

111 lines
3.2 KiB

3 years ago
  1. package outwatchapp.components
  2. import colibri.ext.monix._
  3. import com.softwaremill.tagging._
  4. import monix.bio._
  5. import monix.eval.Coeval
  6. import monix.{eval => me}
  7. import outwatch._
  8. import outwatch.dsl._
  9. import outwatch.reactive.handlers.monix._
  10. import outwatchapp.AppTypes
  11. import outwatchapp.implicits._
  12. import outwatchapp.ui.components.todo.Todo
  13. import outwatchapp.ui.components.todo.TodoListStore
  14. import outwatchapp.util.reactive.store.Store
  15. import sttp.client._
  16. sealed trait RequestDemo
  17. object RequestDemo {
  18. def request(query: String)(implicit backend: AppTypes.Backend) = basicRequest
  19. .get(
  20. uri"https://jsonplaceholder.typicode.com/todos/${query.toIntOption.getOrElse(0)}"
  21. )
  22. .send()
  23. .flatMap {
  24. _.body match {
  25. case Right(value) =>
  26. me.Task(println(value)) >> me.Task(value)
  27. case Left(error) =>
  28. me.Task(println(error)) >> me.Task(error)
  29. }
  30. }
  31. def apply(todoStore: Store[TodoListStore.Action, TodoListStore.State])(
  32. implicit backend: AppTypes.Backend
  33. ): Task[HtmlVNode @@ RequestDemo] =
  34. Task.deferAction(implicit s =>
  35. for {
  36. requestSub <- Handler.createF[Task, String]("empty")
  37. todoContent <- Handler.createF[Task, String]
  38. } yield div(
  39. // cls := "col-lg-8 bd-example",
  40. div(cls := "alert alert-danger", "Some Error Occured!"),
  41. div(
  42. form(
  43. h4(cls := "form-title", "User Finder"),
  44. div(
  45. cls := "form-group",
  46. label(
  47. color := "hsla(0,0%,100%,0.8)",
  48. forId := "httpInput",
  49. "Enter an id: "
  50. ),
  51. input(
  52. idAttr := "httpInput",
  53. typ := "text",
  54. cls := "form-control",
  55. placeholder := "0",
  56. onInput.value --> requestSub
  57. )
  58. ),
  59. div(
  60. cls := "form-group",
  61. label(
  62. color := "hsla(0,0%,100%,0.8)",
  63. "Enter content for todo"
  64. ),
  65. input(
  66. cls := "form-control",
  67. onInput.value --> todoContent
  68. ),
  69. button(
  70. cls := "btn",
  71. cls := "btn-info form-control",
  72. "Add Todo",
  73. onClick.preventDefault.foreachSync(_ =>
  74. Coeval(println("Clicked"))
  75. ),
  76. onClick(
  77. todoContent.map(TodoListStore.Add)
  78. ) --> todoStore.sink
  79. )
  80. )
  81. )
  82. ),
  83. div(
  84. p(
  85. cls := "text-white",
  86. requestSub
  87. .doOnNext(str => me.Task(println(str)))
  88. .mapEval(request)
  89. .map(div(_)),
  90. div(
  91. "Todos: ",
  92. todoStore
  93. .map { case (a, s) => s.todos }
  94. // .doOnNextF { case (a, s) => Coeval(println(s)) }
  95. .distinctUntilChanged
  96. .map(renderTodos)
  97. )
  98. )
  99. )
  100. ).taggedWith[RequestDemo]
  101. )
  102. def renderTodos(todos: Seq[Todo]) = div(
  103. ul(
  104. todos.map(todo => li(div(s"id: ${todo.id} content: ${todo.content}")))
  105. )
  106. )
  107. }