diff options
Diffstat (limited to 'editor')
| -rwxr-xr-x | editor/actions.ml | 22 | ||||
| -rwxr-xr-x | editor/editor.ml | 124 | 
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      ()    | _, _, _ -> | 
