open Brr module PM = Prosemirror module Js = Js_of_ocaml.Js module Storage = Storage (** This is the state for the application *) type t = { editable : bool ; view : PM.View.editor_view Js.t ; last_backup: float ; page_id: Jstr.t option ; window : Brr.El.t list ; pm : PM.t } (** Compare two states together. The prosemirror elemens are ignored *) let eq s1 s2 = Stdlib.(==) ( s1.editable , s1.last_backup , s1.page_id , s1.window ) ( s2.editable , s2.last_backup , s2.page_id , s2.window ) let set_title : Storage.content Js.t -> unit = fun content -> let title = Js.Opt.get content##.title (fun () -> Jstr.empty) in let title_element = Document.find_el_by_id G.document (Jstr.v "title") in Option.iter (fun el -> El.set_prop (El.Prop.value) title el) title_element 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 content##.content (fun () -> let obj = PM.State.creation_prop () in obj##.plugins := Plugins.default pm schema; obj##.schema := Js.some schema; PM.State.create pm obj) (fun page_content -> let obj = PM.State.configuration_prop () in obj##.plugins := Plugins.default pm schema; obj##.schema := Js.some schema; PM.State.fromJSON pm obj page_content) let load_page : Jstr.t option -> t -> t = fun page_id state -> let json = Storage.load page_id in let editor_state = state_of_storage state.pm json state.view##.state##.schema in let () = state.view##updateState editor_state and () = set_title json in let last_backup = Js.Opt.case json##.date (fun () -> state.last_backup ) (fun v -> v) in { state with page_id ; last_backup } let new_page : Jstr.t option -> title:Jstr.t -> t -> t = fun page_id ~title state -> 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 let editor_state = state_of_storage state.pm content_obj state.view##.state##.schema in let () = state.view##updateState editor_state and () = set_title content_obj in let last_backup = Js.Opt.case content_obj##.date (fun () -> state.last_backup ) (fun v -> v) in { state with page_id ; last_backup } let init : PM.t -> PM.View.editor_view Js.t -> float -> Jstr.t option -> t = fun pm view last_backup page_id -> { editable = true ; view ; last_backup ; page_id ; window = [] ; pm }