Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integrate learn-ocaml-editor #295

Draft
wants to merge 99 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
99 commits
Select commit Hold shift + click to select a range
21887b6
feat: learn-ocaml-editor version 0.1.0
erikmd Jun 23, 2019
58f6eb2
feat: learn-ocaml-editor version 0.2.0
erikmd Jun 23, 2019
afd3b1a
feat: learn-ocaml-editor version 0.3.0
erikmd Jun 23, 2019
b23ae00
feat: learn-ocaml-editor version 0.4.0
erikmd Jun 24, 2019
33a94b5
Merge remote-tracking branch 'upstream/master' into learn-ocaml-editor
leunam217 Jul 5, 2019
d748d65
refactor: Remove unneeded files
erikmd Jul 5, 2019
f417bfc
fix: teacher's Check feature in "Test" tab
erikmd Jul 6, 2019
59f0207
fix: teacher's Check feature in "Test" tab
erikmd Jul 6, 2019
a61bc99
fix : fix metadata fields
leunam217 Jul 12, 2019
1d2052d
refactor : some refactor of editor.ml
leunam217 Jul 15, 2019
1430be1
feat : add experiment feature also update exo_creator
leunam217 Jul 15, 2019
9a1140f
feat : zip export of 1 exercise
leunam217 Jul 16, 2019
6809473
feat : add zip import for one exercise , also did some refactor
leunam217 Jul 18, 2019
4139663
feat : Add export all
leunam217 Jul 18, 2019
bac422c
fix : remove the saving of editor exercise to the state of a proper e…
leunam217 Jul 18, 2019
d23c987
feat(export) : add a folder in the zip when exporting one exercise
leunam217 Jul 19, 2019
d82eb94
feat (import all): finish Editor_io
leunam217 Jul 19, 2019
15780b5
feat : add beforeunload management
leunam217 Jul 19, 2019
7d76dde
refactor: refactor the majority of dialog boxes with learn_ocaml_comm…
leunam217 Jul 22, 2019
c55c234
refacor : update copyright messages
leunam217 Jul 22, 2019
c082d9d
fix : New exercise display is correct
leunam217 Jul 22, 2019
c9840c8
fix : fix the problem of getting prompt when trying to exit the edito…
leunam217 Jul 22, 2019
5d58ab5
refactor : remove useless template generation when generating the tes…
leunam217 Jul 22, 2019
3b115d1
fix : add more expressive message when is an error in the authors field
leunam217 Jul 22, 2019
ff7e53c
feat : add id display in exercise list
leunam217 Jul 22, 2019
9581ace
refactor: Simplify the code of genTemplate
erikmd Jul 22, 2019
c65c805
Merge branch 'learn-ocaml-editor' of github.com:pfitaxel/learn-ocaml …
leunam217 Jul 22, 2019
75bf894
refactor : simplify the id handling in Editor_io.upload
leunam217 Jul 22, 2019
09cd3cb
feat : Add override all option when importing
leunam217 Jul 23, 2019
f59835c
fix(localStorage.clear) : Temporary workaround :
leunam217 Jul 23, 2019
d81f3d6
feat : Add the possibility to import an exercise even with missing files
leunam217 Jul 23, 2019
5add660
fix (new_exercise.ml) : restoring the information of fields when they…
leunam217 Jul 23, 2019
bebd99c
feat: Improve "Generate" to group questions about the same function
erikmd Jul 23, 2019
df4dd5c
fix: Add more helpful message when there's an error in field authors
leunam217 Jul 22, 2019
04005b0
feat: add id display in exercise list
leunam217 Jul 22, 2019
cef5c93
refactor: Simplify the code of genTemplate
erikmd Jul 22, 2019
caec3fa
refactor: simplify the id handling in Editor_io.upload
leunam217 Jul 22, 2019
beefd63
feat: Add override all option when importing
leunam217 Jul 23, 2019
27d95df
fix(localStorage.clear): Temporary workaround:
leunam217 Jul 23, 2019
d6098c1
feat: Add the possibility to import an exercise even with missing files
leunam217 Jul 23, 2019
f411cbb
fix(new_exercise.ml): restoring the information of fields when they'r…
leunam217 Jul 23, 2019
9cde33e
feat: Improve "Generate" to group questions about the same function
erikmd Jul 23, 2019
840a14d
feat : add generate 1 dropup
leunam217 Jul 24, 2019
0681084
feat : add insert and get_cursor_position to ace.ml
leunam217 Jul 24, 2019
605d2f7
feat : add against solution template
leunam217 Jul 24, 2019
f184a7d
feat : add templates to the local storage
leunam217 Jul 26, 2019
21cbbd5
feat : add templates configuration menu
leunam217 Aug 6, 2019
b5508a6
feat : templates beta version
leunam217 Aug 7, 2019
54ff959
feat : add auto recovering for the exercise when saving templates con…
leunam217 Aug 7, 2019
11a5b00
wip
leunam217 Aug 9, 2019
91942d6
feat : add json mode to template's configuration editor
leunam217 Aug 9, 2019
5bde0b7
refactor : add explanation in the templates configuration
leunam217 Aug 9, 2019
7e297c5
feat : Add research bar for all templates vue
leunam217 Aug 9, 2019
39ff8c1
feat : add 'markdown ocaml' syntax for the edition of templates
leunam217 Aug 9, 2019
e3551b2
feat : change the mode of the template's configuration editor
leunam217 Aug 9, 2019
fec482f
fix : fix a bug when editing templates see the comment added in edito…
leunam217 Aug 9, 2019
971b40f
refactor : put custom html components into a module in editor_lib
leunam217 Aug 9, 2019
123e82f
fix : remove all_templates vue when applying a template
leunam217 Aug 15, 2019
b10c1e3
Merge branch 'master' into learn-ocaml-editor
yurug Oct 6, 2019
f09c0cd
Merge remote-tracking branch 'upstream/master' into learn-ocaml-editor
erikmd Feb 1, 2020
bebed70
Simplify src/editor/test_spec.ml using [%funty: int -> int] syntax
erikmd Feb 1, 2020
3bb8678
docs: Add TODOs
erikmd Feb 1, 2020
597856b
fix: Workaround ocaml-sf/learn-ocaml#300
erikmd Feb 1, 2020
2509add
Merge branch 'generate1' into learn-ocaml-editor
erikmd Aug 12, 2020
f5b3514
Merge branch 'fix-static-deploy' into learn-ocaml-editor
erikmd Dec 12, 2020
9bde825
fix(src/editor/dune): Missing package spec
erikmd Nov 25, 2020
cda2fa4
fix: missing "Editor" button in static deployment mode
erikmd Dec 12, 2020
31c463f
fix(merge): learn-ocaml-editor + static deployment
erikmd Dec 12, 2020
bc55e7e
feat: integrate the exercice's number in the title
LouisAyroles May 6, 2021
b868d62
fix: click on a hyperlink in the html generate by markdown open it in…
LouisAyroles May 10, 2021
a6f335c
fix: hyperlink's text can be bold or any type of more complex mardown…
LouisAyroles May 10, 2021
c6c1a86
fix: style modification to make the code more elegant
LouisAyroles May 11, 2021
1624bbc
fix: replace the iFrame question pane by a div to avoid blinking and …
LouisAyroles May 12, 2021
3f6673c
fix: resolve few problems with CSS on the editor view
LouisAyroles May 12, 2021
046b3e9
fix: internal links were open in a new tab, also quick refactoring of…
LouisAyroles May 14, 2021
cbdec8d
fix: update overrideurl to handle escape character in URL
LouisAyroles May 18, 2021
85e8055
fix(opam): "odoc" constraint
erikmd Dec 13, 2020
b4a0fc4
fix: editor/editor.ml
erikmd Dec 31, 2020
a595709
fix: avoid Invalid_argument "Learnocaml_toplevel.protect_execution"
erikmd Jan 5, 2021
ec7f365
fix(static/*.html): Add missing leading slash or baseUrl
erikmd Jan 5, 2021
1693e95
fix(learnocaml_exercise_main.ml): Add missing baseUrl prefix
erikmd Jan 6, 2021
283ae61
fix(editor.ml): Loading of "/js/learnocaml-toplevel-worker.js"
erikmd Jan 6, 2021
53dff98
fix(editor_lib.ml): Add missing api_server prefix
erikmd Jan 6, 2021
991430b
refactor(learnocaml_exercise_main.ml): Remove duplicate code
erikmd Jan 6, 2021
f4ffac8
fix(learnocaml_editor_tab.ml): Add missing api_server prefix
erikmd Jan 6, 2021
ab0f4f0
docs: Add todo-refactor
erikmd Jan 6, 2021
44cd018
fix(learnocaml_common.mli): Expose (box_button, close_button)
erikmd Jan 9, 2021
af85f61
fix: Remove unused 'rec'
erikmd Jan 10, 2021
a06f37e
fix: Isolate & Workaround the Stack_overflow raised by 'Experiment'
erikmd Jan 10, 2021
7db3731
Merge remote-tracking branch 'origin/master' into learn-ocaml-editor
erikmd Jul 7, 2021
828efb5
Merge remote-tracking branch 'upstream/master' into learn-ocaml-editor
erikmd Aug 12, 2021
388e338
feat: Add property enableEditor
erikmd Aug 26, 2021
4a2601f
feat: Move editor files apart
erikmd Aug 26, 2021
7689962
QoL: Add a set_progress command in learn-ocaml-editor/Test/Generate
erikmd Aug 26, 2021
24fc021
fix: potential name clash in learn-ocaml-editor/Test/Generate
erikmd Aug 27, 2021
507a7d3
fix: s/Fonction/Function/
erikmd Aug 27, 2021
95af8d2
QoL: Specify a JS-RegExp pattern in <input type="text" id="authors" …>
erikmd Aug 30, 2021
1a047a5
QoL: Reverse the order of items in <select id="difficulty" …>
erikmd Aug 30, 2021
8aa71e6
docs: Improve the default text in learn-ocaml-editor/Question
erikmd Aug 31, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion learn-ocaml.opam
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ depends: [
"ocp-indent-nlfork"
"ocp-ocamlres" {>= "0.4"}
"ocplib-json-typed" {= "0.6"}
"odoc" {build & >= "1.3.0"}
"odoc" {build & >= "1.4.0"}
"omd" {<= "1.3.1"}
"pprint"
"ppx_cstruct"
Expand Down
8 changes: 8 additions & 0 deletions src/ace-lib/ace.ml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ let create_range s e =

let read_position pos = (pos##.row, pos##.column)

let get_cursor_position {editor} = editor##(getCursorPosition)

let read_range range =
((range##.start##.row, range##.start##.column),
(range##.end_##.row, range##.end_##.column))
Expand Down Expand Up @@ -92,6 +94,12 @@ let set_custom_data { editor } data =
let set_mode {editor} name =
editor##getSession##(setMode (Js.string name))

let on {editor} event callback =
editor##getSession##(on (Js.string event) (Js.Unsafe.meth_callback callback))

let insert {editor} position content =
editor##getSession##(insert position (Js.string content))

type mark_type = Error | Warning | Message

let string_of_make_type: mark_type -> string = function
Expand Down
4 changes: 4 additions & 0 deletions src/ace-lib/ace.mli
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ type loc = {
val create_editor: Dom_html.divElement Js.t -> 'a editor

val set_mode: 'a editor -> string -> unit
val on: 'b editor -> string -> (Dom_html.event Js.t -> unit) -> unit
val insert: 'a editor -> Ace_types.position Js.t -> string -> unit


val read_range: Ace_types.range Js.t -> (int * int) * (int * int)
val create_range:
Expand All @@ -28,6 +31,7 @@ val create_position: int -> int -> Ace_types.position Js.t
val read_position: Ace_types.position Js.t -> int * int
val greater_position:
Ace_types.position Js.t -> Ace_types.position Js.t -> bool
val get_cursor_position: 'a editor -> Ace_types.position Js.t

val get_contents: ?range:Ace_types.range Js.t -> 'a editor -> string
val get_line: 'a editor -> int -> string
Expand Down
4 changes: 4 additions & 0 deletions src/ace-lib/ace_types.mli
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ class type editSession = object
method getTokenAt : int -> int -> token Js.t Js.meth
method replace : range Js.t -> Js.js_string Js.t -> unit Js.meth
method setMode : Js.js_string Js.t -> unit Js.meth
method on : Js.js_string Js.t ->
((Dom_html.event Js.t , unit) Js.meth_callback)->
unit Js.meth
method insert : position Js.t -> Js.js_string Js.t -> unit Js.meth
method setAnnotations : annotation Js.t Js.js_array Js.t -> unit Js.meth
method getAnnotations : annotation Js.t Js.js_array Js.t Js.meth
method clearAnnotations : unit Js.meth
Expand Down
9 changes: 6 additions & 3 deletions src/app/dune
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
learnocaml_data
learnocaml_api
sha
grading_jsoo
ocplib_i18n)
)

Expand All @@ -38,13 +39,14 @@
learnocaml_app_common
learnocaml_toplevel
js_of_ocaml.ppx
ocplib_i18n)
ocplib_i18n
learnocaml_editor_tab)
(modules Learnocaml_teacher_tab
Learnocaml_index_main)
(preprocess (pps ppx_ocplib_i18n js_of_ocaml.ppx))
(js_of_ocaml
(flags :standard +cstruct/cstruct.js)
(javascript_files ../ace-lib/ace_bindings.js))
(javascript_files ../ace-lib/ace_bindings.js ../../static/js/jszip/learnocaml_jszip_wrapper.js))
)

(executable
Expand All @@ -59,7 +61,8 @@
learnocaml_app_common
learnocaml_toplevel
js_of_ocaml.ppx
ocplib_i18n)
editor_lib
ocplib_i18n)
(modules Learnocaml_exercise_main)
(preprocess (pps ppx_ocplib_i18n js_of_ocaml.ppx))
(js_of_ocaml
Expand Down
50 changes: 45 additions & 5 deletions src/app/learnocaml_common.ml
Original file line number Diff line number Diff line change
Expand Up @@ -113,12 +113,12 @@ let ext_alert ~title ?(buttons = [close_button [%i"OK"]]) message =
Manip.(appendChild Elt.body) div;
div in
Manip.replaceChildren div [
H.div [
H.h3 [ H.txt title ];
H.div message;
H.div ~a:[ H.a_class ["buttons"] ] buttons;
H.div [
H.h3 [ H.pcdata title ];
H.div message;
H.div ~a:[ H.a_class ["buttons"] ] buttons;
]
]
]

let lwt_alert ~title ~buttons message =
let waiter, wakener = Lwt.task () in
Expand Down Expand Up @@ -1230,3 +1230,43 @@ module Display_exercise =
[ focus ; requirements ; backward ; forward ]
])
end

module Grade_exercise = struct

let get_grade =
let get_worker = get_worker_code "learnocaml-grader-worker.js" in
fun ?callback ?timeout exercise ->
get_worker () >>= fun worker_js_file ->
Grading_jsoo.get_grade ~worker_js_file ?callback ?timeout exercise

let display_report exo report =
let score, _failed = Report.result report in
let report_button = find_component "learnocaml-exo-button-report" in
Manip.removeClass report_button "success" ;
Manip.removeClass report_button "failure" ;
Manip.removeClass report_button "partial" ;
let grade =
let max = Learnocaml_exercise.(access File.max_score exo) in
if max = 0 then 999 else score * 100 / max
in
if grade >= 100 then begin
Manip.addClass report_button "success" ;
Manip.replaceChildren report_button
Tyxml_js.Html5.[ pcdata [%i"Report"] ]
end else if grade = 0 then begin
Manip.addClass report_button "failure" ;
Manip.replaceChildren report_button
Tyxml_js.Html5.[ pcdata [%i"Report"] ]
end else begin
Manip.addClass report_button "partial" ;
let pct = Format.asprintf "%2d%%" grade in
Manip.replaceChildren report_button
Tyxml_js.Html5.[ pcdata [%i"Report"] ;
span ~a: [ a_class [ "score" ] ] [ pcdata pct ]]
end ;
let report_container = find_component "learnocaml-exo-tab-report" in
Manip.setInnerHtml report_container
(Format.asprintf "%a" Report.(output_html ~bare: true) report) ;
grade

end
18 changes: 18 additions & 0 deletions src/app/learnocaml_common.mli
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@ val fatal : ?title: string -> string -> unit

val alert : ?title: string -> ?buttons: Html_types.div_content Tyxml_js.Html.elt list -> string -> unit

val box_button :
string Tyxml_js.Html5.wrap -> (unit -> 'a) ->
[> Html_types.button ] Tyxml_js.Html5.elt

val close_button :
string Tyxml_js.Html5.wrap ->
[> Html_types.button ] Tyxml_js.Html5.elt

val ext_alert :
title: string ->
?buttons: Html_types.div_content_fun Tyxml_js.Html.elt list ->
Expand Down Expand Up @@ -277,3 +285,13 @@ module Display_exercise :functor
'a Learnocaml_data.token option ->
Learnocaml_data.Exercise.Meta.t -> string -> unit Lwt.t
end

module Grade_exercise : sig
val get_grade :
?callback:(string -> unit) ->
?timeout:float ->
Learnocaml_exercise.t ->
(string -> (Learnocaml_report.t * string * string * string) Lwt.t) Lwt.t
val display_report :
Learnocaml_exercise.t -> Learnocaml_data.Report.t -> int
end
1 change: 1 addition & 0 deletions src/app/learnocaml_config.ml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class type learnocaml_config = object
method enableTryocaml: bool Js.optdef_prop
method enableLessons: bool Js.optdef_prop
method enableExercises: bool Js.optdef_prop
method enableEditor: bool Js.optdef_prop
method enableToplevel: bool Js.optdef_prop
method enablePlayground: bool Js.optdef_prop
method txtLoginWelcome: Js.js_string Js.t Js.optdef_prop
Expand Down
1 change: 1 addition & 0 deletions src/app/learnocaml_config.mli
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class type learnocaml_config = object
method enableTryocaml: bool Js.optdef_prop
method enableLessons: bool Js.optdef_prop
method enableExercises: bool Js.optdef_prop
method enableEditor: bool Js.optdef_prop
method enableToplevel: bool Js.optdef_prop
method enablePlayground: bool Js.optdef_prop
method txtLoginWelcome: Js.js_string Js.t Js.optdef_prop
Expand Down
84 changes: 42 additions & 42 deletions src/app/learnocaml_exercise_main.ml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ open Lwt.Infix
open Learnocaml_common
open Learnocaml_data
open Learnocaml_config
open Grade_exercise

module H = Tyxml_js.Html

Expand All @@ -34,42 +35,6 @@ let check_if_need_refresh has_server =
else
Lwt.return_unit

let get_grade =
let get_worker = get_worker_code "learnocaml-grader-worker.js" in
fun ?callback ?timeout exercise ->
get_worker () >>= fun worker_js_file ->
Grading_jsoo.get_grade ~worker_js_file ?callback ?timeout exercise

let display_report exo report =
let score, _failed = Report.result report in
let report_button = find_component "learnocaml-exo-button-report" in
Manip.removeClass report_button "success" ;
Manip.removeClass report_button "failure" ;
Manip.removeClass report_button "partial" ;
let grade =
let max = Learnocaml_exercise.(access File.max_score exo) in
if max = 0 then 999 else score * 100 / max
in
if grade >= 100 then begin
Manip.addClass report_button "success" ;
Manip.replaceChildren report_button
Tyxml_js.Html5.[ txt [%i"Report"] ]
end else if grade = 0 then begin
Manip.addClass report_button "failure" ;
Manip.replaceChildren report_button
Tyxml_js.Html5.[ txt [%i"Report"] ]
end else begin
Manip.addClass report_button "partial" ;
let pct = Format.asprintf "%2d%%" grade in
Manip.replaceChildren report_button
Tyxml_js.Html5.[ txt [%i"Report"] ;
span ~a: [ a_class [ "score" ] ] [ txt pct ]]
end ;
let report_container = find_component "learnocaml-exo-tab-report" in
Manip.setInnerHtml report_container
(Format.asprintf "%a" Report.(output_html ~bare: true) report) ;
grade

module Exercise_link =
struct
let exercise_link ?(cl = []) id content =
Expand All @@ -79,9 +44,9 @@ module Exercise_link =
]
content
end
module Display = Display_exercise(Exercise_link)
open Display

module Display = Display_exercise(Exercise_link)
open Display

let is_readonly = ref false

Expand All @@ -91,6 +56,13 @@ let make_readonly () =
[%i"The deadline for this exercise has expired. Any changes you make \
from now on will remain local only."]

(* experiment button of editor.html redirects to the html associated to this ml
to know if we are in this page because of that we decide
to put a '.' before the id
therefore idEditor looks for a '.' before the id *)

let idEditor s = not ((Regexp.string_match (Regexp.regexp "^[.]+") s 0) = None)

let () =
run_async_with_log @@ fun () ->
set_string_translations_exercises ();
Expand All @@ -115,12 +87,27 @@ let () =
in
Dom_html.document##.title :=
Js.string (id ^ " - " ^ "Learn OCaml" ^" v."^ Learnocaml_api.version);
let exercise_fetch =
token >>= fun token ->
retrieve (Learnocaml_api.Exercise (token, id))

(* if we came from a true exercise we search in the server.
In the other case we get the exercise information from the Local storage *)
(* FIXME: for debug purposes; to be removed:
let ok str = lwt_alert ~title:"TEST1" ~buttons:["OK", (fun () -> Lwt.return_unit)]
[ H.p [H.txt (String.trim str)] ] in *)
let exercise_fetch = match idEditor id with
| false -> token >>= fun token ->
retrieve (Learnocaml_api.Exercise (token, id))

| true -> let proper_id = String.sub id 1 ((String.length id)-1) in
let state = Editor_lib.get_editor_state proper_id in
(* FIXME: for debug purposes; to be removed:
ok state.Editor.metadata.title >>= fun () -> *)
let exo = Editor_lib.exo_creator proper_id in
Lwt.return (state.Editor.metadata, exo, None)
in

let after_init top =
exercise_fetch >>= fun (_meta, exo, _deadline) ->

begin match Learnocaml_exercise.(decipher File.prelude exo) with
| "" -> Lwt.return true
| prelude ->
Expand Down Expand Up @@ -196,6 +183,18 @@ let () =
(* ---- main toolbar -------------------------------------------------- *)
let exo_toolbar = find_component "learnocaml-exo-toolbar" in
let toolbar_button = button ~container: exo_toolbar ~theme: "light" in
let () =
if idEditor id then
begin
let id = String.sub id 1 ((String.length id)-1) in
begin toolbar_button
~icon: "upload" [%i"Edit"] @@ fun ()->
Dom_html.window##.location##assign
(Js.string (api_server ^ "/editor.html#id=" ^ id ^ "&action=open"));
Lwt.return_unit
end;
end
in
begin toolbar_button
~icon: "list" [%i"Exercises"] @@ fun () ->
Dom_html.window##.location##assign
Expand All @@ -208,6 +207,7 @@ let () =
let worker =
ref (get_grade ~callback exo)
in

begin toolbar_button
~icon: "typecheck" [%i"Compile"] @@ fun () ->
typecheck true
Expand Down
16 changes: 14 additions & 2 deletions src/app/learnocaml_index_main.ml
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,11 @@ let teacher_tab token a b () =
Learnocaml_teacher_tab.teacher_tab token a b () >>= fun div ->
Lwt.return div

let editor_tab a b () =
show_loading[%i"Loading Editor"] @@ fun () ->
Learnocaml_editor_tab.editor_tab a b () >>= fun div ->
Lwt.return div

let get_stored_token () =
Learnocaml_local_storage.(retrieve sync_token)

Expand Down Expand Up @@ -689,7 +694,12 @@ let () =
then [ "playground", ([%i"Playground"], playground_tab token) ] else []) @
(match token with
| Some t when Token.is_teacher t ->
[ "teacher", ([%i"Teach"], teacher_tab t) ]
[ "teacher", ([%i"Teach"], teacher_tab t) ] @
if get_opt config##.enableEditor then
[ "editor", ([%i"Editor"], editor_tab) ]
else []
| None when get_opt config##.enableEditor ->
[ "editor", ([%i"Editor"], editor_tab) ]
| _ -> [])
in
let container = El.tab_buttons_container in
Expand Down Expand Up @@ -798,8 +808,10 @@ let () =
H.div ~a:[H.a_style "text-align: center;"]
[token_disp_div (get_stored_token ())]]
(fun () ->
Lwt.async @@ fun () ->
Lwt.async @@ fun () ->
let index = Learnocaml_local_storage.(retrieve editor_index) in
Learnocaml_local_storage.clear ();
Learnocaml_local_storage.(store editor_index index);
reload ();
Lwt.return_unit)
in
Expand Down
Loading