diff --git a/src/haz3lschool/Exercise.re b/src/haz3lschool/Exercise.re index 10a62b4294..d972d524f2 100644 --- a/src/haz3lschool/Exercise.re +++ b/src/haz3lschool/Exercise.re @@ -483,6 +483,14 @@ module F = (ExerciseEnv: ExerciseEnv) => { }, }; + let update_exercise_title = ({eds, _} as state: state, new_title: string) => { + ...state, + eds: { + ...eds, + title: new_title, + }, + }; + let visible_in = (pos, ~instructor_mode) => { switch (pos) { | Prelude => instructor_mode diff --git a/src/haz3lweb/Editors.re b/src/haz3lweb/Editors.re index ecb4f55c5f..97b0abff00 100644 --- a/src/haz3lweb/Editors.re +++ b/src/haz3lweb/Editors.re @@ -136,19 +136,15 @@ let set_editing_title = (editors: t, editing: bool): t => Exercises(n, specs, Exercise.set_editing_title(exercise, editing)) }; -let update_exercise_title = - (editors: t, new_title: string, instructor_mode: bool): t => +let update_exercise_title = (editors: t, new_title: string): t => switch (editors) { | Scratch(_) | Documentation(_) => editors - | Exercises(n, specs, _) => + | Exercises(n, specs, exercise) => Exercises( n, - specs, - Exercise.state_of_spec( - {...List.nth(specs, n), title: new_title, module_name: new_title}, - ~instructor_mode, - ), + ListUtil.update_nth(n, specs, spec => {{...spec, title: new_title}}), + Exercise.update_exercise_title(exercise, new_title), ) }; diff --git a/src/haz3lweb/Update.re b/src/haz3lweb/Update.re index 9e55ed917c..2a402be46e 100644 --- a/src/haz3lweb/Update.re +++ b/src/haz3lweb/Update.re @@ -166,12 +166,15 @@ let update_settings = } | InstructorMode => let new_mode = !settings.instructor_mode; + let editors = Editors.set_editing_title(model.editors, false); + let editors = Editors.set_instructor_mode(editors, new_mode); { ...model, - editors: Editors.set_instructor_mode(model.editors, new_mode), + editors, settings: { ...settings, instructor_mode: !settings.instructor_mode, + editing_title: false, }, }; | EditingTitle => @@ -521,14 +524,9 @@ let rec apply = ModelResults.union((_, _a, b) => Some(b), model.results, results); Ok({...model, results}); | UpdateTitle(new_title) => - Ok({ + Model.save_and_return({ ...model, - editors: - Editors.update_exercise_title( - model.editors, - new_title, - model.settings.instructor_mode, - ), + editors: Editors.update_exercise_title(model.editors, new_title), }) }; m |> Result.map(~f=update_cached_data(~schedule_action, update)); diff --git a/src/haz3lweb/view/ExerciseMode.re b/src/haz3lweb/view/ExerciseMode.re index f0f943566a..d2e7d67c7b 100644 --- a/src/haz3lweb/view/ExerciseMode.re +++ b/src/haz3lweb/view/ExerciseMode.re @@ -74,6 +74,18 @@ let view = ); }; + let update_title = _ => { + let new_title = + Obj.magic( + Js_of_ocaml.Js.some(JsUtil.get_elem_by_id("title-input-box")), + )##.value; + let update_events = [ + inject(Set(EditingTitle)), + inject(UpdateTitle(new_title)), + ]; + Virtual_dom.Vdom.Effect.Many(update_events); + }; + let title_view = { Cell.simple_cell_view([ div( @@ -81,35 +93,38 @@ let view = [ settings.instructor_mode ? settings.editing_title - ? input( - ~attr= - Attr.many([ - Attr.class_("title-text"), - Attr.value(eds.title), - Attr.on_keydown(evt => - if (evt##.keyCode === 13) { - let new_title = Obj.magic(evt##.target)##.value; - let update_events = [ - inject(Set(EditingTitle)), - inject(UpdateTitle(new_title)), - ]; - Virtual_dom.Vdom.Effect.Many(update_events); - } else { - // This is placeholder until I figure out how to "do nothing" - inject( - FinishImportAll(None), - ); - } - ), - ]), - [], + ? div( + ~attr=Attr.many([Attr.class_("title-edit")]), + [ + input( + ~attr= + Attr.many([ + Attr.class_("title-text"), + Attr.id("title-input-box"), + Attr.value(eds.title), + ]), + [], + ), + div( + ~attr=Attr.class_("edit-icon"), + [Widgets.button(Icons.confirm, update_title)], + ), + div( + ~attr=Attr.class_("edit-icon"), + [ + Widgets.button(Icons.cancel, _ => + inject(Set(EditingTitle)) + ), + ], + ), + ], ) : div( - ~attr=Attr.many([Attr.class_("title-text")]), + ~attr=Attr.many([Attr.class_("title-edit")]), [ text(eds.title), div( - ~attr=Attr.class_("pencil-icon"), + ~attr=Attr.class_("edit-icon"), [ Widgets.button(Icons.pencil, _ => inject(Set(EditingTitle)) diff --git a/src/haz3lweb/view/Icons.re b/src/haz3lweb/view/Icons.re index 36f9cdf7d7..668a8a9dd6 100644 --- a/src/haz3lweb/view/Icons.re +++ b/src/haz3lweb/view/Icons.re @@ -219,3 +219,19 @@ let pencil = "M403.914,0L54.044,349.871L0,512l162.128-54.044L512,108.086L403.914,0z M295.829,151.319l21.617,21.617L110.638,379.745 l-21.617-21.617L295.829,151.319z M71.532,455.932l-15.463-15.463l18.015-54.043l51.491,51.491L71.532,455.932z M153.871,422.979 l-21.617-21.617l206.809-206.809l21.617,21.617L153.871,422.979z M382.297,194.555l-64.852-64.852l21.617-21.617l64.852,64.852 L382.297,194.555z M360.679,86.468l43.234-43.235l64.853,64.853l-43.235,43.234L360.679,86.468z", ], ); + +let confirm = + simple_icon( + ~view="0 0 32 32", + [ + "m16 0c8.836556 0 16 7.163444 16 16s-7.163444 16-16 16-16-7.163444-16-16 7.163444-16 16-16zm0 2c-7.7319865 0-14 6.2680135-14 14s6.2680135 14 14 14 14-6.2680135 14-14-6.2680135-14-14-14zm6.6208153 9.8786797c.3905243.3905242.3905243 1.0236892 0 1.4142135l-7.0710678 7.0710678c-.3626297.3626297-.9344751.3885319-1.3269928.0777064l-.0872208-.0777064-4.24264068-4.2426407c-.39052429-.3905242-.39052429-1.0236892 0-1.4142135.39052428-.3905243 1.02368928-.3905243 1.41421358 0l3.5348268 3.5348268 6.3646681-6.3632539c.3905243-.3905243 1.0236893-.3905243 1.4142136 0z", + ], + ); + +let cancel = + simple_icon( + ~view="0 0 32 32", + [ + "m16 0c8.836556 0 16 7.163444 16 16s-7.163444 16-16 16-16-7.163444-16-16 7.163444-16 16-16zm0 2c-7.7319865 0-14 6.2680135-14 14s6.2680135 14 14 14 14-6.2680135 14-14-6.2680135-14-14-14zm4.2426407 9.7573593c.3905243.3905243.3905243 1.0236893 0 1.4142136l-2.8284271 2.8284271 2.8284271 2.8284271c.3905243.3905243.3905243 1.0236893 0 1.4142136s-1.0236893.3905243-1.4142136 0l-2.8284271-2.8284271-2.8284271 2.8284271c-.3905243.3905243-1.0236893.3905243-1.4142136 0s-.3905243-1.0236893 0-1.4142136l2.8284271-2.8284271-2.8284271-2.8284271c-.3905243-.3905243-.3905243-1.0236893 0-1.4142136s1.0236893-.3905243 1.4142136 0l2.8284271 2.8284271 2.8284271-2.8284271c.3905243-.3905243 1.0236893-.3905243 1.4142136 0z", + ], + ); diff --git a/src/haz3lweb/www/style.css b/src/haz3lweb/www/style.css index fa0ac1aa24..4b87fa7d2a 100644 --- a/src/haz3lweb/www/style.css +++ b/src/haz3lweb/www/style.css @@ -722,18 +722,24 @@ select { font-size: 1.5rem; font-weight: bold; color: var(--light-text-color); +} + +.title-cell .title-edit { + font-size: 1.5rem; + font-weight: bold; + color: var(--light-text-color); flex-grow: 1; display: flex; align-items: center; } -.title-cell .pencil-icon { +.title-edit .edit-icon { margin-left: 0.5em; cursor: pointer; - color: #7a6219; + fill: #7a6219; } -.title-cell .pencil-icon:hover { +.title-edit .edit-icon:hover { animation: wobble 0.6s ease 0s 1 normal forwards; }