summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xeditor/actions/add_page.ml8
-rwxr-xr-xeditor/actions/delete_page.ml3
-rwxr-xr-xeditor/actions/editor_actions.ml11
-rwxr-xr-xeditor/actions/export.ml16
-rwxr-xr-xeditor/actions/import.ml31
-rwxr-xr-xeditor/actions/load_page.ml3
-rwxr-xr-xeditor/forms/selector.ml47
-rwxr-xr-xeditor/state/state.ml26
-rwxr-xr-xeditor/state/state.mli5
-rwxr-xr-xeditor/state/storage.ml24
-rwxr-xr-xeditor/state/storage.mli3
11 files changed, 149 insertions, 28 deletions
diff --git a/editor/actions/add_page.ml b/editor/actions/add_page.ml
index 4a3fcf3..e5e8541 100755
--- a/editor/actions/add_page.ml
+++ b/editor/actions/add_page.ml
@@ -13,13 +13,7 @@ module M = struct
: t -> State.t -> State.t
= fun {title} state ->
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.new_page ~title (Some page_id) state
end
(** Create a new element *)
diff --git a/editor/actions/delete_page.ml b/editor/actions/delete_page.ml
index fb600bd..58c1d32 100755
--- a/editor/actions/delete_page.ml
+++ b/editor/actions/delete_page.ml
@@ -9,8 +9,7 @@ module M = struct
| None -> state
| Some page_id ->
State.Storage.delete (fun () -> Some page_id);
- let json = State.Storage.load None in
- State.load_page None state json
+ State.load_page None state
end
diff --git a/editor/actions/editor_actions.ml b/editor/actions/editor_actions.ml
index 8c47363..70b078b 100755
--- a/editor/actions/editor_actions.ml
+++ b/editor/actions/editor_actions.ml
@@ -72,11 +72,17 @@ let populate_menu
add_button)
and export_event =
+ Evr.on_el
+ Ev.click
+ (fun _ -> Export.create ())
+ export_button
+
+ and import_event =
Note.E.join (
Evr.on_el
Ev.click
- (fun _ -> Export.create ())
- export_button)
+ (fun _ -> Import.create ())
+ load_button)
in
@@ -147,4 +153,5 @@ let populate_menu
; redirect_event
; add_event
; export_event
+ ; import_event
])
diff --git a/editor/actions/export.ml b/editor/actions/export.ml
index a97eeac..71e3b64 100755
--- a/editor/actions/export.ml
+++ b/editor/actions/export.ml
@@ -31,16 +31,8 @@ end
(** Create a new element *)
let create
- : unit -> State.event Note.event
+ : unit -> State.event
= fun () ->
- let title = Jstr.v "Confirmation"
- and message = Jstr.v "Exporter les notes" in
- let ev = Elements.Popup.create
- ~title
- ~form:(Some (Forms.Validation.create message ))
- in
- Note.E.map
- (fun v -> State.E
- ( v
- , (module M : State.Event with type t = M.t )))
- (Note.E.Option.on_some ev)
+ State.E
+ ( ()
+ , (module M : State.Event with type t = M.t ))
diff --git a/editor/actions/import.ml b/editor/actions/import.ml
new file mode 100755
index 0000000..fd4bef8
--- /dev/null
+++ b/editor/actions/import.ml
@@ -0,0 +1,31 @@
+module Js = Js_of_ocaml.Js
+
+module M = struct
+
+ type t = Forms.Selector.t
+
+ let update
+ : t -> State.t -> State.t
+ = fun t state ->
+ match t with
+ | None -> state
+ | Some file ->
+ (* Back to UTF-16 *)
+ let content = file.Forms.Selector.content in
+ Brr.Console.(log [content] );
+ match State.Storage.of_json content with
+ | Error _ -> state
+ | Ok _obj ->
+ State.load_page state.State.page_id state
+end
+
+let create () =
+ let title = Jstr.v "Importer des notes" in
+ let ev = Elements.Popup.create
+ ~title
+ ~form:(Some (Forms.Selector.create ())) in
+ Note.E.map
+ (fun v -> State.E
+ ( v
+ , (module M : State.Event with type t = M.t )))
+ (Note.E.Option.on_some ev)
diff --git a/editor/actions/load_page.ml b/editor/actions/load_page.ml
index ceee038..349eaad 100755
--- a/editor/actions/load_page.ml
+++ b/editor/actions/load_page.ml
@@ -5,8 +5,7 @@ module M = struct
let update
: t -> State.t -> State.t
= fun page_id state ->
- let json = State.Storage.load page_id in
- State.load_page page_id state json
+ State.load_page page_id state
end
diff --git a/editor/forms/selector.ml b/editor/forms/selector.ml
new file mode 100755
index 0000000..1354dcc
--- /dev/null
+++ b/editor/forms/selector.ml
@@ -0,0 +1,47 @@
+open Brr
+
+type file =
+ { file : File.t
+ ; content : Jstr.t
+ }
+
+type t = file option
+
+(** Read the content from the file *)
+let file_loader
+ : file option Note.E.send -> File.t -> unit
+ = fun event file ->
+ let blob = File.as_blob file in
+ Fut.await
+ (Blob.text blob)
+ (Result.iter
+ (fun content ->
+ event (Some {file; content}) ))
+let create
+ : unit -> t Note.signal * Brr.El.t
+ = fun () ->
+
+ let add_file_event, add_file_sender = Note.E.create () in
+
+ let i = El.input ()
+ ~at:[ At.type' (Jstr.v "file")
+ ; (At.v (Jstr.v "accept")) (Jstr.v ".json")
+ ] in
+
+ (* The event return a list of files.
+
+ We are only interested by a single on, and keep only the first from the
+ list. *)
+ let on_change files =
+ file_loader add_file_sender (List.hd files) in
+
+ Ev.listen
+ Ev.change
+ (fun _e -> on_change (El.Input.files i)) (El.as_target i);
+
+ let state = Note.S.hold
+ None
+ add_file_event
+ in
+ ( state
+ , i )
diff --git a/editor/state/state.ml b/editor/state/state.ml
index 649473c..2662a48 100755
--- a/editor/state/state.ml
+++ b/editor/state/state.ml
@@ -60,8 +60,9 @@ let state_of_storage
PM.State.fromJSON pm obj page_content)
let load_page
- : Jstr.t option -> t -> Storage.content Js.t -> t
- = fun page_id state json ->
+ : 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
@@ -74,6 +75,27 @@ let load_page
{ 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
diff --git a/editor/state/state.mli b/editor/state/state.mli
index 20d5288..2f3e9c4 100755
--- a/editor/state/state.mli
+++ b/editor/state/state.mli
@@ -22,7 +22,10 @@ val state_of_storage
: Prosemirror.t -> Storage.content Js.t -> Prosemirror.Model.schema Js.t -> Prosemirror.State.editor_state Js.t
val load_page
- : Jstr.t option -> t -> Storage.content Js.t -> t
+ : Jstr.t option -> t -> t
+
+val new_page
+ : Jstr.t option -> title:Jstr.t -> t -> t
(** Initialise a new state *)
val init
diff --git a/editor/state/storage.ml b/editor/state/storage.ml
index a790a9d..1bb8b81 100755
--- a/editor/state/storage.ml
+++ b/editor/state/storage.ml
@@ -157,3 +157,27 @@ let to_json
(* Also add the home page *)
let pages = Array.of_list @@ (save_for_id None)::pages in
Brr.Json.encode (Jv.Id.to_jv pages)
+
+let of_json
+ : Jstr.t -> (unit, Jv.Error.t) result
+ = fun json ->
+ let result = Json.decode json in
+ Result.map
+ (fun v ->
+ Array.iter (Jv.Id.of_jv v)
+ ~f:(fun element ->
+ let key = element##.id
+ and content = object%js
+ val title = element##.title
+ val content = element##.content
+ val date = element##.date
+ end in
+ ignore @@
+ save
+ ~check:(fun _ -> true)
+ content
+ key
+ ))
+ result
+
+
diff --git a/editor/state/storage.mli b/editor/state/storage.mli
index 50e164e..4d022d1 100755
--- a/editor/state/storage.mli
+++ b/editor/state/storage.mli
@@ -37,3 +37,6 @@ val get_ids
val to_json
: unit -> Jstr.t
+
+val of_json
+ : Jstr.t -> (unit, Jv.Error.t) result