From bf94695abeda0d7bb296ae4cd0f9a53782587d4a Mon Sep 17 00:00:00 2001 From: Sébastien Dailly Date: Mon, 7 Feb 2022 16:14:09 +0100 Subject: Update editor organisation --- editor/app.ml | 118 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100755 editor/app.ml (limited to 'editor/app.ml') diff --git a/editor/app.ml b/editor/app.ml new file mode 100755 index 0000000..aee396a --- /dev/null +++ b/editor/app.ml @@ -0,0 +1,118 @@ +open Brr +module PM = Prosemirror +module Js = Js_of_ocaml.Js + +type events = + | DeleteEvent + | StoreEvent + | LoadEvent of Jstr.t option + | AddEvent + | CloseEvent of Forms.Events.kind option + | GEvent of Forms.Events.event + +let key_of_title + : Jstr.t -> Jstr.t + = fun title -> + title + +(** [update] is the event loop. + + The function take a new event, and apply it to the current state. *) + +let update + : 'a option Note.E.send -> (events, State.t) Application.t + = fun close_sender event state -> + match event with + + | GEvent (Event (t, (module Handler))) -> + Handler.on_close t state + + | AddEvent -> + let title = Jstr.v "Nouvelle page" in + let popup = Ui.popup + ~title + ~form:(Some (Forms.Add_page.create ())) + close_sender in + { state with window = popup::state.window} + + | DeleteEvent -> + begin match state.page_id with + | None -> state + | Some page_id -> + let title = Jstr.v "Confirmation" in + let popup = Ui.popup + ~title + ~form:(Some (Forms.Delete_page.create page_id)) + close_sender in + { state with window = popup::state.window} + end + + | CloseEvent res -> + + let state = match state.window with + | [] -> { state with window = [] } + | el::tl -> El.remove el + ; { state with window = tl } in + + (* The actions is confirmed by the user. Handle the form result *) + begin match res with + (* Delete the current page, then load the home page *) + | Some (Forms.Delete_page.DeletePage id) -> + State.Storage.delete (fun () -> Some id); + let json = State.Storage.load None in + State.load_page None state json + (* Add a new page *) + | Some (Forms.Add_page.AddPage {title}) -> + let page_id = key_of_title title in + let new_date = (new%js Js.date_now)##getTime in + let content_obj = object%js + val content = Js.null + val title = Js.some title + val date = Js.some new_date + end in + State.load_page (Some page_id) state content_obj + + | _ -> state + end + + | StoreEvent -> + + let title_element = Document.find_el_by_id G.document (Jstr.v "title") in + let content = Option.map + (fun el -> El.prop (El.Prop.value) el) + title_element in + + 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.Opt.option content + val date = Js.some new_date + end in + let save = State.Storage.save + content_obj + state.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 } + | other -> + (* TODO In case of error, notify the user *) + Console.(log [other]); + state + end + + | LoadEvent page_id -> + let json = State.Storage.load page_id in + State.load_page page_id state json + + -- cgit v1.2.3