commit 6f5d7287bb56531c0bc9dac925c118acd3e0c768 parent 9dd53309109abc2a7298f8bdb63aeb0ce0914fce Author: Yohanes Bandung <bandungpenting@gmail.com> Date: Fri, 9 Aug 2019 22:19:59 +0700 feature(Scene) => added CurVi scene Diffstat:
| A | src/App.re | | | 9 | +++++++++ |
| A | src/CurVi.re | | | 35 | +++++++++++++++++++++++++++++++++++ |
| M | src/Index.re | | | 8 | ++++++-- |
| A | src/Utils.re | | | 34 | ++++++++++++++++++++++++++++++++++ |
| M | src/index.html | | | 6 | ++---- |
| A | src/registerServiceWorker.js | | | 51 | +++++++++++++++++++++++++++++++++++++++++++++++++++ |
6 files changed, 137 insertions(+), 6 deletions(-)
diff --git a/src/App.re b/src/App.re @@ -0,0 +1,9 @@ +[@react.component] +let make = () => { + let url = ReasonReact.Router.useUrl(); + + switch (url.path) { + | [] => <CurVi /> + | _ => <CurVi /> + } +} diff --git a/src/CurVi.re b/src/CurVi.re @@ -0,0 +1,35 @@ +type state = { + opened: string, + dark: bool, +}; + +type section = Quest | Info | Contact; +let convert = (s: section) => +switch s { + | Quest => "quest" + | Info => "info" + | Contact => "contact" +}; + +type action = + | ToggleDark + | Open((section)); + +let initialState = {opened: "quest", dark: false}; + +[@react.component] +let make = () => { + let (state, _) = + React.useReducer ( + (state, action) => + switch (action) { + | ToggleDark => {...state, dark: !state.dark} + | Open((toOpen)) => {...state, opened: convert( toOpen )}; + }, + initialState, + ); + + <div> + {ReasonReact.createElement(span, _, state.opened)} + </div> +} diff --git a/src/Index.re b/src/Index.re @@ -1,3 +1,7 @@ -ReactDOMRe.renderToElementWithId(<Component1 message="Hello! Click this text." />, "index1"); +open Utils; -ReactDOMRe.renderToElementWithId(<Component2 greeting="Hello!" />, "index2"); +registerServiceWorker(); + +ReactDOMRe.renderToElementWithId(<App />, "root"); + +ReasonReact.Router.push(""); diff --git a/src/Utils.re b/src/Utils.re @@ -0,0 +1,34 @@ +/* to enable require css file */ +[@bs.val] external requireCSS: string => unit = "require"; + +/* to get Date.now */ +[@bs.val] external currentTime: unit => int = "Date.now"; + +/* format a timestamp in seconds as relative humanised time sentence */ +let fromNow = unixtime => { + let delta = currentTime() / 1000 - unixtime; + if (delta < 3600) { + string_of_int(delta / 60) ++ " minutes ago"; + } else if (delta < 86400) { + string_of_int(delta / 3600) ++ " hours ago"; + } else { + string_of_int(delta / 86400) ++ " days ago"; + }; +}; + +/* extras JS function */ +[@bs.send] [@bs.return nullable] +external getAttribute: (Js.t('a), string) => option(string) = "getAttribute"; + +let dangerousHtml: string => Js.t('a) = html => {"__html": html}; + +let distanceFromBottom: unit => int = + () => { + let bodyClientHeight = [%raw "document.body.clientHeight"]; + let windowScrollY = [%raw "window.scrollY"]; + let windowInnerHeight = [%raw "window.innerHeight"]; + bodyClientHeight - (windowScrollY + windowInnerHeight); + }; + +/* registerServiceWorker */ +[@bs.module] external registerServiceWorker: unit => unit = "src/registerServiceWorker"; diff --git a/src/index.html b/src/index.html @@ -5,11 +5,9 @@ <title>ReasonReact Examples</title> </head> <body> - Component 1: - <div id="index1"></div> - Component 2: - <div id="index2"></div> + <div id="root"></div> + <noscript>Please enable Javascript to use this app.</noscript> <script src="Index.js"></script> </body> diff --git a/src/registerServiceWorker.js b/src/registerServiceWorker.js @@ -0,0 +1,51 @@ +// In production, we register a service worker to serve assets from local cache. + +// This lets the app load faster on subsequent visits in production, and gives +// it offline capabilities. However, it also means that developers (and users) +// will only see deployed updates on the "N+1" visit to a page, since previously +// cached resources are updated in the background. + +// To learn more about the benefits of this model, read https://goo.gl/KwvDNy. +// This link also includes instructions on opting out of this behavior. + +module.exports = function register() { + if (process.env.NODE_ENV === "production" && "serviceWorker" in navigator) { + window.addEventListener("load", function() { + var swUrl = process.env.PUBLIC_URL + "/service-worker.js"; + navigator.serviceWorker + .register(swUrl) + .then(function(registration) { + registration.onupdatefound = function() { + var installingWorker = registration.installing; + installingWorker.onstatechange = function() { + if (installingWorker.state === "installed") { + if (navigator.serviceWorker.controller) { + // At this point, the old content will have been purged and + // the fresh content will have been added to the cache. + // It's the perfect time to display a "New content is + // available; please refresh." message in your web app. + console.log("New content is available; please refresh."); + } else { + // At this point, everything has been precached. + // It's the perfect time to display a + // "Content is cached for offline use." message. + console.log("Content is cached for offline use."); + } + } + }; + }; + }) + .catch(function(error) { + console.error("Error during service worker registration:", error); + }); + }); + } +}; + +module.exports.unregister = function unregister() { + if ("serviceWorker" in navigator) { + navigator.serviceWorker.ready.then(function(registration) { + registration.unregister(); + }); + } +};