Created
June 26, 2019 20:11
-
-
Save MangelMaxime/76c5d55999e867a6292945ac2cdb1843 to your computer and use it in GitHub Desktop.
"Pure Elmish" implementation of TIME FLIES LIKE AN ARROW example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
html, | |
body { | |
font-size: 16px; | |
} | |
.main-container { | |
display: flex; | |
width: 100%; | |
height: 100%; | |
justify-content: center; | |
align-items: center; | |
flex-direction: column; | |
} | |
.input { | |
padding: .25rem; | |
font-size: 16px; | |
width: 250px; | |
margin-bottom: 1rem; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Thoth.RandomUser | |
open Fable.Core | |
open Fable.React | |
open Fable.React.Props | |
open Browser | |
open Elmish | |
open Elmish.React | |
let getOffset (element: Browser.Types.Element) = | |
let doc = element.ownerDocument | |
let docElem = doc.documentElement | |
let clientTop = docElem.clientTop | |
let clientLeft = docElem.clientLeft | |
let scrollTop = window.pageYOffset | |
let scrollLeft = window.pageXOffset | |
int (scrollTop - clientTop), int (scrollLeft - clientLeft) | |
let container = document.querySelector "#elmish-app" | |
let top, left = getOffset container | |
// The model holds data that you want to keep track of while the | |
// application is running | |
type Model = { | |
Letters: Map<int, string * int * int> | |
} | |
// The Msg type defines what events/actions can occur while the | |
// application is running. The state of the application changes *only* | |
// in reaction to these events | |
type Msg = | |
| Letter of int * string * int * int | |
// The update function computes the next state of the application based | |
// on the current state and the incoming messages | |
let update (msg : Msg) (currentModel : Model) = | |
match currentModel.Letters, msg with | |
| _, Letter (i, c, x, y) -> | |
{ currentModel with Letters = currentModel.Letters.Add (i, (c, x, y)) }, Cmd.none | |
let onMouseMove (f: Types.Event->unit) = | |
window.addEventListener("mousemove", f) | |
{ new System.IDisposable with | |
member __.Dispose() = | |
window.removeEventListener("mousemove", f) } | |
type TextViewProps = | |
{ | |
Model : Model | |
Dispatch : Dispatch<Msg> | |
} | |
let textView = | |
FunctionComponent.Of( | |
fun (props : TextViewProps) -> | |
Hooks.useEffectDisposable(fun () -> | |
onMouseMove (fun ev -> | |
props.Model.Letters | |
|> Map.toList | |
|> List.iter (fun (index, (c, x, y)) -> | |
window.setTimeout(fun () -> | |
let ev = ev :?> Types.MouseEvent | |
let clientX = int ev.clientX + index * 10 + 15 - left | |
let clientY = int ev.clientY - top | |
(index, c, clientX, clientY) | |
|> Letter | |
|> props.Dispatch | |
, 100 * index) | |
|> ignore | |
) | |
) | |
, [| props.Model.Letters |]) | |
let letters = | |
props.Model.Letters | |
|> Map.toList | |
|> List.map (fun (index, (c, x, y)) -> | |
span [ | |
Style | |
[ | |
Top y | |
Left x | |
Position (PositionOptions.Fixed) | |
] | |
] | |
[ str c ] | |
) | |
|> ofList | |
div [ Style [ FontFamily "Consolas, monospace"; Height "100%"] ] | |
[ letters | |
] | |
, "Text.View" | |
, equalsButFunctions | |
) | |
let view (model : Model) (dispatch : Dispatch<Msg>) = | |
textView | |
{ | |
Model = model | |
Dispatch = dispatch | |
} | |
let init () = | |
let cmds = | |
Seq.toList "TIME FLIES LIKE AN ARROW" | |
|> Seq.mapi (fun i c -> | |
let msg = Letter (i, string c, 0, 0) | |
Cmd.ofMsg msg | |
) | |
|> Cmd.batch | |
{ Letters = Map.empty }, cmds | |
// App | |
Program.mkProgram init update view | |
|> Program.withReactSynchronous "elmish-app" | |
|> Program.run |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
<meta http-equiv='Content-Type' content='text/html; charset=utf-8'> | |
<script src="__HOST__/libs/react.production.min.js"></script> | |
<script src="__HOST__/libs/react-dom.production.min.js"></script> | |
<link rel="stylesheet" href="__HOST__/libs/css/bulma.min.css" /> | |
<link rel="stylesheet" href="__HOST__/libs/css/all.min.css" /> | |
</head> | |
<body class="app-container"> | |
<script type="text/javascript"> | |
window.throttle = function (callback, wait, immediate) { | |
let timeout = null | |
let initialCall = true | |
return function () { | |
const callNow = immediate && initialCall | |
const next = () => { | |
callback.apply(this, arguments) | |
timeout = null | |
} | |
if (callNow) { | |
initialCall = false | |
next() | |
} | |
if (!timeout) { | |
timeout = setTimeout(next, wait) | |
} | |
} | |
} | |
</script> | |
<div id="elmish-app" class="elmish-app"></div> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment