Skip to content

Instantly share code, notes, and snippets.

@camwest
Last active June 7, 2018 19:45
Show Gist options
  • Select an option

  • Save camwest/e038188f94d091bb9ea4dadadc69b945 to your computer and use it in GitHub Desktop.

Select an option

Save camwest/e038188f94d091bb9ea4dadadc69b945 to your computer and use it in GitHub Desktop.
Login
Login
Login Cached?
cached? -> Enter Credentials
not cached? -> Login Downloading
Login Downloading
downloaded -> Enter Credentials
Enter Credentials
login success -> File Manager
Without Error
error -> With Error
With Error
clear -> Without Error
Logged In
log out -> Enter Credentials
File Manager
File Manager Cached?
cached? -> Browsing Files
not cached? -> File Manager Downloading
File Manager Downloading
downloaded -> Browsing Files
Browsing Files
click -> DWG Editor
DWG Editor
back -> Browsing Files
DWG Editor Cached?
cached? -> Editing
not cached? -> Downloading DWG Editor
Downloading DWG Editor
downloaded -> Editing
Editing
// Average connection speeds kilobytes per second
const AUTO_FORWARD = false;
const SPEED_20_MB = 2500;
const SPEED_5_MB = 625;
// The speed used in the prototype
const KB_PER_SECOND = SPEED_5_MB; // 20 megabit connection
// File size in KB of various JavaScript bundles
const LOGIN_DOWNLOAD_KB = 200;
const FILE_MANAGER_DOWNLOAD_KB = 1000;
const DWG_EDITOR_DOWNLOAD_KB = 1000;
// CACHES
const WARM_START = false;
const FILE_MANAGER_CACHED = WARM_START;
const LOGIN_CACHED = WARM_START;
const DWG_EDITOR_CACHED = WARM_START;
function LoggedInHeader({ onLogout }) {
return $("ul", $("li", $("button", { onClick: onLogout }, "Logout")));
}
function Editing({ onLogout }) {
return $(
Dialog,
{ title: "Browser" },
$("div", $(LoggedInHeader, { onLogout: onLogout }), "Editing DWG File")
);
}
function FilesList({ onFileSelected, onLogout }) {
return $(
Dialog,
{ title: "Browser" },
$(LoggedInHeader, { onLogout: onLogout }),
$(
"ul",
$(
"li",
$(
"a",
{ href: "javascript:void(0)", onClick: onFileSelected },
"Drawing 1.dwg"
)
),
$(
"li",
$(
"a",
{ href: "javascript:void(0)", onClick: onFileSelected },
"Drawing 2.dwg"
)
),
$(
"li",
$(
"a",
{ href: "javascript:void(0)", onClick: onFileSelected },
"Drawing 3.dwg"
)
)
)
);
}
function HTTPCache({ fetch, onCacheHit, onCacheMiss }) {
return $(
Dialog,
{ title: "HTTP Cache" },
`Fetching ${fetch}`,
$(
"div",
$("button", { onClick: onCacheHit }, "Cache Hit"),
$("button", { onClick: onCacheMiss }, "Cache Miss")
)
);
}
function Dialog({ title, children }) {
return $(
"div",
{
style: {
border: "solid 1px black",
borderRadius: "8px",
padding: "8px",
margin: "8px",
flexGrow: 1
}
},
title ? $("h1", title) : null,
children
);
}
class Loading extends React.Component {
componentDidMount() {
if (AUTO_FORWARD) {
setTimeout(() => {
this.props.onDownloaded();
}, this.downloadDuration() * 1000);
}
}
downloadDuration() {
return this.props.fileSize / KB_PER_SECOND;
}
render() {
return $(
Dialog,
{ title: "Browser" },
$(
"div",
$("p", this.props.label),
$("p", `Download Duration: ${this.downloadDuration()} seconds`),
$("button", { onClick: this.props.onDownloaded }, "Downloaded")
)
);
}
}
function Login() {
return $(
"form",
$("p", "Valid username: camwest"),
$("p", $("label", "Username"), $("input", { type: "text" }))
);
}
function UnknownState({ label }) {
return $("p", "Non Visual State: ", label);
}
function ErrorMessage({ errorMessage, onClear }) {
return $(
"p",
{ style: { color: "red", fontWeight: "bold" } },
$("span", errorMessage),
$("button", { onClick: onClear }, "X")
);
}
function EnterCredentials({
errorMessage,
onLoginSuccess,
onLoginError,
onClearError
}) {
return $(
Dialog,
errorMessage !== ""
? ErrorMessage({ errorMessage, onClear: onClearError })
: null,
$(
"p",
$("label", { style: { marginRight: "18px" } }, "Username"),
$("input", { type: "text", value: "camwest" })
),
$(
"p",
$("label", { style: { marginRight: "18px" } }, "Password"),
$("input", { type: "password", value: "abc123" })
),
$(
"p",
$("input", {
type: "submit",
value: "Login (success)",
onClick: onLoginSuccess
}),
$("input", {
type: "submit",
value: "Login (fail)",
onClick: onLoginError
})
)
);
}
function renderState(activeState, emit) {
switch (activeState) {
case "Login Cached?":
return $(HTTPCache, {
fetch: "/login.js",
onCacheHit: () => emit("cached?"),
onCacheMiss: () => emit("not cached?")
});
case "File Manager Cached?":
return $(HTTPCache, {
fetch: "/filemanager.js",
onCacheHit: () => emit("cached?"),
onCacheMiss: () => emit("not cached?")
});
case "Login Downloading":
return $(Loading, {
label: "Downloading Login",
fileSize: LOGIN_DOWNLOAD_KB,
onDownloaded: () => emit("downloaded")
});
case "Without Error":
return EnterCredentials({
errorMessage: "",
onLoginSuccess: () => emit("login success"),
onLoginError: () => emit("error"),
onClearError: () => emit("clear")
});
case "With Error":
return EnterCredentials({
errorMessage: "Invalid Username/Password",
onLoginSuccess: () => emit("login success"),
onLoginError: () => emit("error"),
onClearError: () => emit("clear")
});
case "File Manager Downloading":
return $(Loading, {
label: "Downloading File Manager",
fileSize: FILE_MANAGER_DOWNLOAD_KB,
onDownloaded: () => emit("downloaded")
});
case "Browsing Files":
return $(FilesList, {
onFileSelected: () => emit("click"),
onLogout: () => emit("log out")
});
case "DWG Editor Cached?":
return $(HTTPCache, {
fetch: "/dwg-editor.js",
onCacheHit: () => emit("cached?"),
onCacheMiss: () => emit("not cached?")
});
case "Downloading DWG Editor":
return $(Loading, {
label: "Downloading DWG Editor",
fileSize: DWG_EDITOR_DOWNLOAD_KB,
onDownloaded: () => emit("downloaded")
});
case "Editing":
return $(Editing, { onLogout: () => emit("log out") });
default:
return UnknownState({ label: activeState });
}
}
function render(model) {
return $(
"div",
{
style: {
display: "flex",
justifyContent: "center",
height: "100%",
widht: "100%"
}
},
renderState(model.active_states[0].name, model.emit)
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment