summaryrefslogtreecommitdiff
path: root/editor/editor.ml
diff options
context:
space:
mode:
authorSébastien Dailly <sebastien@chimrod.com>2021-04-29 15:20:11 +0200
committerSébastien Dailly <sebastien@dailly.me>2022-02-07 16:43:33 +0100
commit2fc4e793b12341df6264e22c0b8bd0f6dd2bd27d (patch)
treeb61b55dc11e4361927c1638d1eb4e82feeef5465 /editor/editor.ml
parenteb319516fd922ab89b7120a885d1e801fa3f45aa (diff)
Added pop-up and events in editor
Diffstat (limited to 'editor/editor.ml')
-rwxr-xr-xeditor/editor.ml136
1 files changed, 120 insertions, 16 deletions
diff --git a/editor/editor.ml b/editor/editor.ml
index fccaa76..d3a9624 100755
--- a/editor/editor.ml
+++ b/editor/editor.ml
@@ -7,11 +7,34 @@ type state =
{ editable : bool
; view : PM.View.editor_view Js.t
; last_backup: float
+ ; page_id: Jstr.t option
+
+ ; window : El.t list
}
type events =
| DeleteEvent
| StoreEvent
+ | LoadEvent of Jstr.t option
+ | AddEvent
+ | CloseEvent of Forms.Events.kind option
+
+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 key_of_title
+ : Jstr.t -> Jstr.t
+ = fun title ->
+ title
let state_of_storage
: PM.t -> Storage.content Js.t -> PM.Model.schema Js.t -> PM.State.editor_state Js.t
@@ -22,8 +45,7 @@ let state_of_storage
let obj = PM.State.creation_prop () in
obj##.plugins := Plugins.default pm schema;
obj##.schema := Js.some schema;
- PM.State.create pm obj
- )
+ PM.State.create pm obj)
(fun page_content ->
let obj = PM.State.configuration_prop () in
obj##.plugins := Plugins.default pm schema;
@@ -36,9 +58,8 @@ let state_of_storage
*)
let build_view
- : El.t -> PM.View.editor_view Js.t * float
- = fun editor ->
- let pm = PM.v () in
+ : PM.t -> Jstr.t option -> El.t -> PM.View.editor_view Js.t * float
+ = fun pm page_id editor ->
(* Remove all the elements if any *)
El.set_children editor [];
@@ -62,8 +83,7 @@ let build_view
(Some custom_schema##.spec##.marks)
None in
let full_schema = PM.Model.schema pm specs in
- (* Load the cache for the given page *)
- let stored_content = Storage.load Storage.page_id in
+ let stored_content = Storage.load page_id in
(* This variable contains the last update time, either because it is
stored, or because it is the date where we create the first page. *)
@@ -85,26 +105,88 @@ let build_view
props in
view, last_backup
+let load_page
+ : PM.t -> Jstr.t option -> state -> Storage.content Js.t -> state
+ = fun pm page_id state json ->
+ let editor_state = state_of_storage pm json state.view##.state##.schema in
+ let () = state.view##updateState editor_state
+ and () = set_title json in
+ { state with page_id }
+
(** [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 ->
+ : PM.t -> 'a option Note.E.send -> (events, state) Application.t
+ = fun pm close_sender event state ->
match event with
+
+ | 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 ->
- state
+ 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) ->
+ Storage.delete (fun () -> Some id);
+ let json = Storage.load None in
+ load_page pm None state json
+ (* Add a new page *)
+ | Some (Forms.Add_page.AddPage {title}) ->
+ let page_id = key_of_title title in
+ Console.(log [title]);
+ 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
+ load_page pm (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.null
+ val title = Js.Opt.option content
val date = Js.some new_date
end in
let save = Storage.save
content_obj
- Storage.page_id
+ state.page_id
~check:(fun previous_state ->
Js.Opt.case previous_state##.date
(fun () -> true)
@@ -119,9 +201,16 @@ let update
date <= state.last_backup)) in
begin match save with
| Ok true -> { state with last_backup = new_date }
- | _ -> state
+ | _ ->
+ (* TODO In case of error, notify the user *)
+ state
end
+ | LoadEvent page_id ->
+ let json = Storage.load page_id in
+ load_page pm page_id state json
+
+
let app id content =
(* Check the pre-requisite *)
@@ -129,22 +218,37 @@ let app id content =
match (Jv.is_none id), (Jv.is_none content), events_opt with
| false, false, Some btn_events ->
+ let pm = PM.v () in
let editor:El.t = Jv.Id.of_jv id in
- let view, last_backup = build_view editor in
+ (* Load the cache for the given page *)
+ let page_id = Storage.page_id () in
+ let view, last_backup = build_view pm page_id editor in
+
+
+ (* This event is used in the pop process. The sender is given to the
+ subroutine in order to track the window closing *)
+ let event, sender = Note.E.create () in
+ let _ = sender in
let init_state =
{ editable = true
; view
; last_backup
+ ; page_id
+
+ ; window = []
}
in
let app_state = Application.run
- update
+ (update pm sender)
init_state
(Note.E.select
- [ Note.E.map (fun () -> DeleteEvent) (snd btn_events.Actions.delete)
+ [ Note.E.map (fun () -> DeleteEvent) btn_events.Actions.delete
; Brr_note.Evr.on_el Ev.focusout (fun _ -> StoreEvent) editor
+ ; Note.E.map (fun v -> LoadEvent v) btn_events.Actions.redirect
+ ; Note.E.map (fun () -> AddEvent) btn_events.Actions.add
+ ; Note.E.map (fun v -> CloseEvent v) event
]) in
let () =