summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSébastien Dailly <sebastien@dailly.me>2022-02-07 16:12:05 +0100
committerSébastien Dailly <sebastien@dailly.me>2022-02-07 16:43:33 +0100
commiteb319516fd922ab89b7120a885d1e801fa3f45aa (patch)
tree88e676a2f913fbd76501783c4c09ce33ddc8d0df
parent37485464a4da41462fc285d03229221f44860397 (diff)
Enjoy the Application pattern
-rwxr-xr-xeditor/actions.ml22
-rwxr-xr-xeditor/editor.ml124
2 files changed, 67 insertions, 79 deletions
diff --git a/editor/actions.ml b/editor/actions.ml
index c02584f..3b17dae 100755
--- a/editor/actions.ml
+++ b/editor/actions.ml
@@ -3,7 +3,7 @@ open Brr
open Brr_note
type button_actions =
- { edit : El.t * (unit Note.event)
+ { delete : El.t * (unit Note.event)
}
let populate_menu () =
@@ -13,21 +13,21 @@ let populate_menu () =
let () = Blog.Sidebar.clean element in
let uri = Brr.Window.location Brr.G.window in
- let edit_button = El.button
+ let delete_button = El.button
~at:At.[ class' (Jstr.v "action-button") ]
[ El.i
[]
~at:At.[ class' (Jstr.v "fa")
; class' (Jstr.v "fa-2x")
- ; class' (Jstr.v "fa-pen")
+ ; class' (Jstr.v "fa-trash")
]
] in
- let edit_event =
+ let delete_event =
Evr.on_el
Ev.click
Evr.unit
- edit_button in
+ delete_button in
let pages =
@@ -52,7 +52,6 @@ let populate_menu () =
; class' (Jstr.v "fa-2x")
; class' (Jstr.v "fa-home") ]
]
- ; edit_button
; El.button
~at:At.[class' (Jstr.v "action-button")]
[ El.i
@@ -69,14 +68,7 @@ let populate_menu () =
; class' (Jstr.v "fa-2x")
; class' (Jstr.v "fa-download") ]
]
- ; El.button
- ~at:At.[class' (Jstr.v "action-button")]
- [ El.i
- []
- ~at:At.[ class' (Jstr.v "fa")
- ; class' (Jstr.v "fa-2x")
- ; class' (Jstr.v "fa-trash") ]
- ]
+ ; delete_button
; El.button
~at:At.[class' (Jstr.v "action-button")]
[ El.i
@@ -92,5 +84,5 @@ let populate_menu () =
let () = El.append_children element childs in
Some
- { edit = (edit_button, edit_event)
+ { delete = (delete_button, delete_event)
}
diff --git a/editor/editor.ml b/editor/editor.ml
index 53a6029..fccaa76 100755
--- a/editor/editor.ml
+++ b/editor/editor.ml
@@ -5,12 +5,15 @@ module Js = Js_of_ocaml.Js
(** This is the state for the application *)
type state =
{ editable : bool
+ ; view : PM.View.editor_view Js.t
+ ; last_backup: float
}
type events =
- | EditEvent
+ | DeleteEvent
+ | StoreEvent
-let editor_of_storage
+let state_of_storage
: PM.t -> Storage.content Js.t -> PM.Model.schema Js.t -> PM.State.editor_state Js.t
= fun pm content schema ->
Js.Opt.case
@@ -27,20 +30,14 @@ let editor_of_storage
obj##.schema := Js.some schema;
PM.State.fromJSON pm obj page_content)
-let update
- : (events, state) Application.t
- = fun event state ->
- match event with
- | EditEvent ->
- { editable = not state.editable }
+(** Create a new editor view
-let init_state =
- { editable = true
- }
+ [build_view element state] will create the editor and attach it to [element].
+*)
let build_view
- : El.t -> state Note.S.t -> PM.View.editor_view Js.t * float ref
- = fun editor app_state ->
+ : El.t -> PM.View.editor_view Js.t * float
+ = fun editor ->
let pm = PM.v () in
(* Remove all the elements if any *)
@@ -70,14 +67,12 @@ let build_view
(* This variable contains the last update time, either because it is
stored, or because it is the date where we create the first page. *)
- let last_backup = ref @@ Js.Opt.get
+ let last_backup = Js.Opt.get
stored_content##.date
(fun () -> (new%js Js.date_now)##getTime) in
let props = PM.View.direct_editor_props () in
- props##.state := editor_of_storage pm stored_content full_schema;
- props##.editable := Js.wrap_callback @@ (fun _state ->
- Js.bool ( (Note.S.value app_state).editable) );
+ props##.state := state_of_storage pm stored_content full_schema;
(* Add the custom nodes *)
props##.nodeViews := PM.O.init
@@ -90,6 +85,43 @@ let build_view
props in
view, last_backup
+(** [update] is the event loop.
+
+ The function take a new event, and apply it to the current state. *)
+let update
+ : (events, state) Application.t
+ = fun event state ->
+ match event with
+ | DeleteEvent ->
+ state
+
+ | StoreEvent ->
+ let new_date = (new%js Js.date_now)##getTime in
+ let content_obj = object%js
+ val content = Js.some @@ Jv.Id.to_jv (state.view##.state##toJSON ())
+ val title = Js.null
+ val date = Js.some new_date
+ end in
+ let save = Storage.save
+ content_obj
+ Storage.page_id
+ ~check:(fun previous_state ->
+ Js.Opt.case previous_state##.date
+ (fun () -> true)
+ (fun date ->
+ (* I do not figure how the previous date could be older
+ than the last backup. It could be either :
+
+ - equal (if we are the only one to update it)
+ - more recent (if the content has been updated elsewhere)
+
+ but older shoud be a bug. *)
+ date <= state.last_backup)) in
+ begin match save with
+ | Ok true -> { state with last_backup = new_date }
+ | _ -> state
+ end
+
let app id content =
(* Check the pre-requisite *)
@@ -98,63 +130,27 @@ let app id content =
| false, false, Some btn_events ->
let editor:El.t = Jv.Id.of_jv id in
+ let view, last_backup = build_view editor in
+
+ let init_state =
+ { editable = true
+ ; view
+ ; last_backup
+ }
+ in
+
let app_state = Application.run
update
init_state
(Note.E.select
- [ Note.E.map (fun () -> EditEvent) (snd btn_events.Actions.edit)
+ [ Note.E.map (fun () -> DeleteEvent) (snd btn_events.Actions.delete)
+ ; Brr_note.Evr.on_el Ev.focusout (fun _ -> StoreEvent) editor
]) in
let () =
Note.S.log app_state (fun _ -> ())
|> Note.Logr.hold in
- (** Map active style of the button with the state *)
- let () =
- Brr_note.Elr.def_class
- (Jstr.v "active")
- (Note.S.map (fun s -> s.editable) app_state)
- (fst btn_events.Actions.edit) in
-
- let view, last_backup = build_view editor app_state in
-
- (* Attach an event on focus out *)
- let _ = Brr_note.Evr.on_el
- (Ev.focusout)
- (fun _ ->
- let new_date = (new%js Js.date_now)##getTime in
- let content_obj = object%js
- val content = Js.some @@ Jv.Id.to_jv (view##.state##toJSON ())
- val title = Js.null
- val date = Js.some new_date
- end in
- let save = Storage.save
- content_obj
- Storage.page_id
- ~check:(fun previous_state ->
- Js.Opt.case previous_state##.date
- (fun () -> true)
- (fun date ->
- (* I do not figure how the previous date could be older
- than the last backup. It could be either :
-
- - equal (if we are the only one to update it)
- - more recent (if the content has been updated elsewhere)
-
- but older shoud be a bug. *)
- date <= !last_backup)) in
- match save with
- | Ok true -> last_backup := new_date
- | _ -> ())
- editor in
-
- let ev =
- Note.E.map
- (fun _ -> view##dispatch view##.state##.tr)
- (Note.S.changes (Note.S.map (fun s -> s.editable) app_state)) in
- let () =
- Note.E.log ev (fun _ -> ())
- |> Option.iter Note.Logr.hold in
()
| _, _, _ ->