From 5c636f11cdfed82634ee572645d765b704941b68 Mon Sep 17 00:00:00 2001 From: Joris Date: Tue, 3 Mar 2020 10:44:35 +0100 Subject: Initialize views from JavaScript --- src/View/timerView.ml | 123 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 src/View/timerView.ml (limited to 'src/View/timerView.ml') diff --git a/src/View/timerView.ml b/src/View/timerView.ml new file mode 100644 index 0000000..2384f85 --- /dev/null +++ b/src/View/timerView.ml @@ -0,0 +1,123 @@ +open CreateElement + +let render (config : Config.config) onStop = + let duration = Config.getDuration config in + (* State *) + let interval = ref None in + let elapsed = ref 0 in + let step = ref (Step.getAt config !elapsed) in + let isPlaying = ref true in + (* Elements *) + let stepElt = text (Step.prettyPrint !step.step) in + let durationElt = text (Duration.prettyPrint !step.remaining) in + let arcPathElt = path ~attributes:[| className "g-Timer__ArcProgress" |] () in + let tabataCurrentElt = text (Js.Int.toString !step.tabata) in + let cycleCurrentElt = text (Js.Int.toString !step.cycle) in + (* Update *) + let stop () = + let () = Belt.Option.forEach !interval Js.Global.clearInterval in + onStop config + in + let updateDom () = + let angle = Js.Int.toFloat !elapsed /. Js.Int.toFloat duration *. 360.0 in + let () = + Element.setAttribute arcPathElt "d" (Arc.describe 0.0 0.0 95.0 0.0 angle) + in + let step = Step.getAt config !elapsed in + let () = Element.setTextContent stepElt (Step.prettyPrint step.step) in + let () = + Element.setTextContent durationElt (Duration.prettyPrint step.remaining) + in + let () = + Element.setTextContent tabataCurrentElt (Js.Int.toString step.tabata) + in + let () = + Element.setTextContent cycleCurrentElt (Js.Int.toString step.cycle) + in + Audio.playFromStep config step + in + let update () = + if !isPlaying then + let () = elapsed := !elapsed + 1 in + let () = step := Step.getAt config !elapsed in + if !elapsed > duration then stop () else updateDom () + else () + in + (* Start timer *) + let () = interval := Some (Js.Global.setInterval update 1000) in + (* View *) + section + ~attributes:[| className "g-Timer" |] + ~children: + [| + button + ~attributes:[| className "g-Timer__Dial" |] + ~eventListeners:[| onClick (fun _ -> isPlaying := not !isPlaying) |] + ~children: + [| + svg + ~attributes: + [| className "g-Timer__Arc"; viewBox "-100 -100 200 200" |] + ~children: + [| + path + ~attributes: + [| + className "g-Timer__ArcTotal"; + d (Arc.describe 0.0 0.0 95.0 0.0 359.999); + |] + (); + arcPathElt; + |] + (); + div + ~attributes:[| className "g-Timer__Step" |] + ~children:[| stepElt |] (); + div + ~attributes:[| className "g-Timer__Duration" |] + ~children:[| durationElt |] (); + |] + (); + div + ~attributes:[| className "g-Timer__TabataAndCycle" |] + ~children: + [| + div + ~attributes:[| className "g-Timer__Tabata" |] + ~children: + [| + div ~children:[| text "Tabata" |] (); + span + ~attributes:[| className "g-Timer__TabataCurrent" |] + ~children:[| tabataCurrentElt |] (); + text "/"; + span + ~attributes:[| className "g-Timer__TabataTotal" |] + ~children:[| text (Js.Int.toString config.tabatas) |] + (); + |] + (); + div + ~attributes:[| className "g-Timer__Cycle" |] + ~children: + [| + div ~children:[| text "Cycle" |] (); + span + ~attributes:[| className "g-Timer__CycleCurrent" |] + ~children:[| cycleCurrentElt |] (); + text "/"; + span + ~attributes:[| className "g-Timer__CycleTotal" |] + ~children:[| text (Js.Int.toString config.cycles) |] + (); + |] + (); + |] + (); + div + ~attributes:[| className "g-Timer__Stop" |] + ~children:[| text "stop" |] + ~eventListeners:[| onClick (fun _ -> stop ()) |] + (); + |] + () -- cgit v1.2.3