Skip to content

Instantly share code, notes, and snippets.

@mithereal
Last active August 27, 2018 21:01
Show Gist options
  • Save mithereal/7bdc25aa9b2667cf5704035ff8b064a8 to your computer and use it in GitHub Desktop.
Save mithereal/7bdc25aa9b2667cf5704035ff8b064a8 to your computer and use it in GitHub Desktop.
bucklescript prob
open Belt ;
type state = {
| LOADING
| ERROR
| LOADED(id) ;
};
type searchType =
| zip ;
type action =
| SEARCHTYPECHANGED(string)
| FETCHCHANNEL
| FETCHEDWS(ws)
| FAILEDTOFETCH ;
type webSocket = {
id: string
}
module Decode = {
let ws = (webSocket) => Json.Decode.{
id: webSocket |> field("id", string)
}
};
let reducer = (action, state) =>
switch(action) {
| SEARCHTYPECHANGED(type) => ReasonReact.Update({...state, searchType: type})
| FETCHCHANNEL => ReasonReact.UpdateWithSideEffects(
LOADING,
(
self =>
Js.Promise.(
Fetch.fetchWithInit(
"/",
Fetch.RequestInit.make(
~method_=Post,
~headers=Fetch.HeadersInit.make({"Content-Type": "application/json"}),
()
)
)
|> then_(Fetch.Response.json)
|> then_(json => json
|> Decode.ws
|> (webSocket => self.send(FETCHEDWS(webSocket.id)))
|> resolve)
|> catch(_err => Js.Promise.resolve(self.send(FAILEDTOFETCH)))
|> ignore
)
),
)
| FETCHEDWS(id) => ReasonReact.Update(LOADED(id))
| FAILEDTOFETCH => ReasonReact.Update(ERROR)
};
let component = ReasonReact.reducerComponent("App");
let make = _children => {
...component,
initialState: () => LOADING,
reducer,
didmount: self => self.send(FETCHCHANNEL),
render: ({state, send}) =>
switch(state){
| ERROR => <div> ( ReasonReact.string("An Error Occured !!") ) </div>
| LOADING => <div className=Styles.app>
<div> ( ReasonReact.string("Loading... ") ) </div>
</div>
| LOADED(id) => <div className=Styles.app>
<Search appState=state appSend=send/>
</div>
}
};
open Phx
let handleReiceive = (event, any) =>
switch event {
| "ok" => Js.log(("handleReiceive:" ++ event, "Joined"))
| "error" => Js.log(("handleReiceive:" ++ event, "Failed to join channel"))
| _ => Js.log(("handleReiceive:" ++ event, any))
};
let handleEvent = (event, response) => {
let _ = Js.log(("handleEvent:" ++ event, response));
();
};
let handleSyncState = (response) => {
let _ = Js.log(("handleSyncState", response));
/*let _ = Js.log (Array.iter (fun key -> Js.log (Js_dict.unsafeGet response key)) (Js_dict.keys response) ) in*/
let _presences = Presence.syncState(Js.Dict.empty(), response);
();
};
let handleSyncDiff = (diff) => {
let _ = Js.log(("handleSyncDiff:diff", diff));
let presences = Presence.syncDiff(Js.Dict.empty(), diff);
let _ = Js.log(("handleSyncDiff:presences", presences));
();
};
{
let socket = initSocket("/socket") |> connectSocket |> putOnClose(() => Js.log("Socket closed"));
let channel = socket |> initChannel("user:lobby");
let _ =
channel
|> putOn("from_server", handleEvent("from:server"))
|> putOnSyncState(handleSyncState)
|> putOnsyncDiff(handleSyncDiff)
|> joinChannel
|> putReceive("ok", handleReiceive("ok"))
|> putReceive("error", handleReiceive("error"));
push("new:message", {"user": "Hello, Elixir! This is a greeting from BuckleScript!"}, channel);
};
let component = ReasonReact.statelessComponent("QuoteItem");
let make = (~quote, _children) => {
...component,
render: (_self) =>
<div className="quote">
</div>,
};
let component = ReasonReact.statelessComponent("QuoteItems");
let make = (~quotes, ~appSend, _children) => {
...component,
render: (_self) =>
(
ReasonReact.arrayToElement(Array.of_list(
List.map((quote) => <QuoteItem quote />, quotes)
))
)
};
[@bs.module "phoenix"]
open Phx
type tQuotes = array(quote)
type quote = {
id: int,
company: string,
profile: string,
price: int
};
type state = {
quotes: tQuotes
}
type action =
| JOINCHANNEL
let reducer = (action, state) =>
switch(action) {
| JOINCHANNEL(socket, channelname) => ??
}
let component = ReasonReact.reducerComponent("Search");
let make = (~appState, ~appSend ,_children) => {
...component,
reducer,
didmount: self =>
let socket = initSocket("/socket") |> connectSocket |> putOnClose(() => Js.log("Socket closed"));
let channel_name = "quote:" ++ appState;
self.send(JOINCHANNEL(socket, channel_name))
render: (self) =>
<Searchtype appState appSend/>
<QuoteItems quotes = self.state.quotes />
};
let component = ReasonReact.statelessComponent("Searchtype");
let make = (~appState: AppState.state, ~appSend, _children) => {
...component,
render: (_self) =>
<div id="search_options">
<ul className="search_options_list">
(
switch appState.searchType {
| zipsearch =>
<li className=Styles.search_options_selected_list_item>{ReasonReact.string("Search by Zipcode")}</li>;
}
)
</ul>
</div>
<div id="search_type">
(
switch appState.searchType {
| zip => <Zipsearch appState=appState appSend=appSend/>
}
)
</div>
};
/*Open the Css module, so we can access the style properties below without prefixing them with Css.*/
open Css;
let card = style([
display(flexBox),
flexDirection(column),
alignItems(stretch),
backgroundColor(white),
boxShadow(~y=px(3), ~blur=px(5), rgba(0, 0, 0, 0.3)),
]);
let header = style([
display(flexBox),
flexDirection(column),
alignItems(stretch),
backgroundColor(white),
boxShadow(~y=px(3), ~blur=px(5), rgba(0, 0, 0, 0.3)),
]);
let search_options_list_item = style([
display(inlineBlock),
width(vw(40.)),
background(yellow),
]);
let search_options_selected_list_item = style([
display(inlineBlock),
width(vw(40.)),
background(green),
]);
let search_zip_form = style(
[width(px(500)),
margin(auto)
]);
let title = style([
fontSize(rem(1.5)),
margin(auto),
]);
let app = style([
fontSize(rem(1.5)),
background( darkgray ),
height(vh(100.)),
]);
let zipcode_input = style([
fontSize(rem(1.5)),
background( darkgray ),
width(vw(30.)),
margin(auto)
]);
let zipcode_submit = style([
fontSize(rem(1.5)),
background( green ),
margin(auto)
]);
let actionButton = disabled =>
style([
background(disabled ? darkgray : white),
color(black),
border(px(1), solid, black),
borderRadius(px(3)),
])
type action =
| SENDREQUEST(string)
| PICKUPZIPCODECHANGED(string)
| DROPOFFZIPCODECHANGED(string)
type state = {
pickupzipcode: string,
dropoffzipcode: string
}
let request = (hash) =>
{
let payload = Js.Dict.empty();
Js.Dict.set(payload, "id", Js.Json.string(hash));
Js.Promise.(
Fetch.fetchWithInit(
"/query",
Fetch.RequestInit.make(
~method_=Post,
~body=Fetch.BodyInit.make(Js.Json.stringify(Js.Json.object_(payload))),
~headers=Fetch.HeadersInit.make({"Content-Type": "application/json"}),
()
)
)
|> then_(Fetch.Response.json)
)
|> ignore;
};
let reducer = (action, state) =>
switch(action) {
DROPOFFZIPCODECHANGED(z) => ReasonReact.Update(...state, pickupzipcode: z)
PICKUPZIPCODECHANGED(z) => ReasonReact.Update(...state, dropoffzipcode: z)
SENDREQUEST(h) => request(h);
ReasonReact.NoUpdate
};
let component = ReasonReact.reducerComponent("Zipsearch");
let make = (~appState, ~appSend, _children) => {
...component,
initialState: () => {pickupzipcode: "", dropoffzipcode: ""},
reducer,
render: (self) =>
<div className=Styles.search_zip_form>
<div className = Styles.zipcode_input>
<input
type_="text"
placeholder="Zipcode"
autoFocus=true
onChange=(
event =>
send(
PICKUPZIPCODECHANGED(
ReactDOMRe.domElementToObj(
ReactEventRe.Form.target(event),
)##value,
),
)
)/>
</div>
<div className = Styles.zipcode_input>
<input
type_="text"
placeholder="Zipcode"
autoFocus=true
onChange=(
event =>
send(
DROPOFFZIPCODECHANGED(
ReactDOMRe.domElementToObj(
ReactEventRe.Form.target(event),
)##value,
),
)
)/>
</div>
<button className = Styles.zipcode_submit onClick=(_event => self.send(SENDREQUEST(appState)))> {ReasonReact.string("Submit")} </button>
</div>
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment