-
Notifications
You must be signed in to change notification settings - Fork 0
/
entrypoint.ml
141 lines (128 loc) · 4.61 KB
/
entrypoint.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
open Kxc_react_helpers
open Kxc_react_native_helpers
let step1_title = "The first step"
let ocaml_version = Sys.ocaml_version
module Guikit = struct
include ReactNative
module Mobile_app_ui = struct
external button :
title:string
-> ?onPress:(_ -> unit)
-> unit
-> React.element
= "Button" [@@mel.module "mobile-app-ui"]
[@@react.component]
end
let button ?key ?onPress title = Mobile_app_ui.button () ?key ?onPress ~title
let text_str ?key ?style str = text_str str ?key ?style:(style >? polydict')
let view ?key ?style children = view children ?key ?style:(style >? polydict')
let hview ?key ?style children = hview children ?key ?style:(style >? polydict')
end
module Imported = struct
external platform_os : string = "OS"
[@@mel.module "react-native"][@@mel.scope "Platform"]
end
module OCaml_section = struct
let log_module = sprintf "OCaml_section.body(os=%s)" Imported.platform_os
let section_title = "Melange (OCaml) Component"
let[@react.component] body ?(initialCounterValue = 0) () =
let open Guikit in
let os_str = match Imported.platform_os with
| "ios" -> "iOS"
| "android" -> "Android"
| os_code -> String.capitalize_ascii os_code
in
let line_break () = text_str "\n" in
let logv fmt = Log0.verbose ~modul:log_module fmt in
let counter, updateCounter = React.useState (constant initialCounterValue) in
fragment [
text_str &
sprintf
"Hello from %s coded using OCaml (more specifically Melange)!"
os_str;
line_break ();
hview ~style:["gap", `int 6; "paddingVertical", `int 4] [
button "Bump"
~onPress:(fun() ->
updateCounter succ;
logv "Bump tapped");
button "Reset"
~onPress:(fun() ->
updateCounter (constant initialCounterValue);
logv "Reset tapped");
];
line_break ();
text_str (sprintf {js|counter = %d|js} counter);
]
end (* module OCaml_section *)
module Accumulator_example = struct
module Style = struct
let container : polydict' = [
"justifyContent", `string "space-evenly"; "flexGrow", `int 1
]
let accumulator : polydict' = [
"textAlign", `string "center";
"fontSize", `int 22;
]
let button : polydict' = [
"flexGrow", `int 1;
]
let prompt ~bingo : polydict' = [
"textAlign", `string "center";
"marginBottom", `int 10;
"fontWeight", `string "bold";
"color", (if bingo then `string "green" else `undefined)
]
let row : polydict' = [
"alignSelf", `string "stretch";
"marginVertical", `int 2;
"marginHorizontal", `string "5%";
"gap", `int 4;
"justifyContent", `string "space-evenly";
"alignItems", `string "stretch";
]
end
let[@react.component] body ?(initialAccumulatorValue = 3) () =
let open Guikit in
let accumulator, updateAccumulator =
React.useState (constant initialAccumulatorValue) in
let mode, updateMode = React.useState (constant (`plus : [ `plus | `minus ])) in
let flip_mode = function `plus -> `minus | `minus -> `plus in
((text_str ~style:Style.accumulator
& sprintf "Accumulator = %d" accumulator;
) :: (
let mode_indicator, mode_effect = match mode with
| `plus -> "+", (+)
| `minus -> "-", Fn.flip (-)
in
let button' ?key ?onPress title =
button title ?key ?onPress
>! view ~style:Style.button in
let row ?key elems = hview elems ?key ~style:Style.row in
let row_of_action_buttons from : int -> React.element =
(iotaf &&> row) &
((+) from) &>
fun x ->
sprintf " %s%d" mode_indicator x
|> button' ~onPress:(fun () -> updateAccumulator (mode_effect x))
in
([ row_of_action_buttons 1 3;
row_of_action_buttons 4 3;
row_of_action_buttons 7 3;
row [
button' "MOD" ~onPress:(fun () ->
updateMode flip_mode);
button' "RST" ~onPress:(fun () ->
updateAccumulator (constant initialAccumulatorValue));
button' "NEG" ~onPress:(fun () ->
updateAccumulator (( * ) (-1)));
];
] |> view) :: [
let bingo = accumulator = 0 in
text_str ~style:(Style.prompt ~bingo)
(if bingo
then "You did it! (tap RST to start over)"
else "Try to get the accumulator value to 0");
])
|> view ~style:Style.container)
end (* module Accumulator_example *)