summaryrefslogtreecommitdiff
path: root/fig-frontend/client/src
diff options
context:
space:
mode:
Diffstat (limited to 'fig-frontend/client/src')
-rw-r--r--fig-frontend/client/src/blueprint.jpgbin0 -> 1308988 bytes
-rw-r--r--fig-frontend/client/src/config.ts3
-rw-r--r--fig-frontend/client/src/index.css30
-rw-r--r--fig-frontend/client/src/index.ts119
-rw-r--r--fig-frontend/client/src/twitch.ts43
5 files changed, 195 insertions, 0 deletions
diff --git a/fig-frontend/client/src/blueprint.jpg b/fig-frontend/client/src/blueprint.jpg
new file mode 100644
index 0000000..6efe89d
--- /dev/null
+++ b/fig-frontend/client/src/blueprint.jpg
Binary files differ
diff --git a/fig-frontend/client/src/config.ts b/fig-frontend/client/src/config.ts
new file mode 100644
index 0000000..5498e16
--- /dev/null
+++ b/fig-frontend/client/src/config.ts
@@ -0,0 +1,3 @@
+export const URL = "http://localhost:8000";
+export const API_URL = "http://localhost:8000/api";
+export const CLIENT_ID = "q486jugzn2my4iw6l181o006ugye4j";
diff --git a/fig-frontend/client/src/index.css b/fig-frontend/client/src/index.css
new file mode 100644
index 0000000..891c5fd
--- /dev/null
+++ b/fig-frontend/client/src/index.css
@@ -0,0 +1,30 @@
+body {
+ margin: 0px;
+ position: absolute;
+ left: 0px;
+ top: 0px;
+ width: 100vw;
+ height: 100vh;
+}
+
+fig-window {
+ display: block;
+ position: absolute;
+}
+
+fig-header {
+ position: absolute;
+ text-align: center;
+ border-radius: 100px;
+ border-style: solid;
+ border-color: silver;
+ border-width: 5px;
+ background: linear-gradient(0deg, rgba(89,89,89,1) 35%, rgba(158,158,158,1) 100%);
+ top: 1em;
+ left: 33vw;
+ width: 33vw;
+}
+
+fig-header:hover {
+ filter: brightness(150%);
+}
diff --git a/fig-frontend/client/src/index.ts b/fig-frontend/client/src/index.ts
new file mode 100644
index 0000000..899c7fd
--- /dev/null
+++ b/fig-frontend/client/src/index.ts
@@ -0,0 +1,119 @@
+import { html, css, LitElement } from "lit";
+import { customElement, property } from "lit/decorators.js";
+
+import interact from "interactjs";
+
+import * as Config from "./config";
+import * as Twitch from "./twitch";
+
+import "./index.css";
+
+console.log("welcome to \"the junkyard\"");
+
+@customElement("fig-window")
+export class Window extends LitElement {
+ x: number;
+ y: number;
+
+ constructor() {
+ super();
+ this.x = 0;
+ this.y = 0;
+ interact(this).draggable({
+ listeners: {
+ move(event) {
+ event.target.x += event.dx
+ event.target.y += event.dy
+ event.target.style.left = `${event.target.x}px`
+ event.target.style.top = `${event.target.y}px`
+ },
+ }
+ });
+ }
+
+ render() {
+ console.log("render");
+ return html`
+<slot></slot>
+`;
+ }
+}
+
+@customElement("fig-backdrop")
+export class Backdrop extends LitElement {
+ static styles = css`
+#backdrop {
+ z-index: -2;
+ position: absolute;
+ left: 0px;
+ top: 0px;
+ width: 100vw;
+ height: 100vh;
+ background-image: url("blueprint.jpg");
+}
+#blur {
+ z-index: -1;
+ backdrop-filter: blur(3px);
+ position: absolute;
+ left: 0px;
+ top: 0px;
+ width: 100vw;
+ height: 100vh;
+ background-size: 100px 100px;
+ background-position: -20px -20px;
+ background-image:
+ linear-gradient(to right, lightgrey 1px, transparent 1px),
+ linear-gradient(to bottom, lightgrey 1px, transparent 1px);
+}
+`;
+ render() {
+ return html`
+<div id="backdrop"></div>
+<div id="blur"></div>
+`;
+ }
+}
+
+@customElement("fig-login")
+export class Login extends LitElement {
+ static styles = css`
+ `;
+
+ login() {
+ Twitch.startTwitchAuth();
+ }
+
+ async check() {
+ const resp = await fetch(`${Config.API_URL}/check`);
+ console.log(await resp.text());
+ }
+
+ render() {
+ const token = Twitch.getAuthToken();
+ console.log(token);
+ if (token) {
+ return html`
+<button @click=${this.check}>check token</button>
+`;
+ } else {
+ return html`
+<button @click=${this.login}>login</button>
+`;
+ }
+ }
+}
+
+@customElement("fig-header")
+export class Header extends LitElement {
+ static styles = css`
+h1 {
+ color: #b5a642;
+ font-family: "Rubik Maps";
+}
+`;
+ render() {
+ return html`
+<h1>Welcome To "The JunkYard"</h1>
+`;
+ }
+}
diff --git a/fig-frontend/client/src/twitch.ts b/fig-frontend/client/src/twitch.ts
new file mode 100644
index 0000000..4c264be
--- /dev/null
+++ b/fig-frontend/client/src/twitch.ts
@@ -0,0 +1,43 @@
+import * as Config from "./config";
+
+function generateNonce(): string {
+ var arr = new Uint8Array(20);
+ window.crypto.getRandomValues(arr);
+ return Array.from(arr, b => b.toString(16).padStart(2, "0")).join("");
+}
+
+export function startTwitchAuth() {
+ const nonce = generateNonce();
+ document.cookie = `authnonce=${nonce}; path=/;`;
+ window.location.href =
+ `https://id.twitch.tv/oauth2/authorize?response_type=id_token`
+ + `&client_id=${Config.CLIENT_ID}`
+ + `&redirect_uri=${Config.URL}`
+ + `&scope=openid`
+ + `&nonce=${nonce}`
+ + `&claims=${{id_token: {preferred_username: null}}}`
+ ;
+}
+
+export function getFragmentQuery(): Map<string, string> {
+ let query = new Map();
+ const hashQuery = document.location.hash.slice(1).split("&");
+ for (let equals of hashQuery) {
+ const pair = equals.split("=");
+ query.set(decodeURIComponent(pair[0]), decodeURIComponent(pair[1]));
+ }
+ return query;
+}
+
+export function getAuthToken(): String | null {
+ const frag = getFragmentQuery();
+ const token = frag.get("id_token");
+ if (token) {
+ document.cookie = `id_token=${token}; path=/; SameSite=Strict`;
+ }
+ for (let c of document.cookie.split("; ")) {
+ const [k, v] = c.split("=");
+ if (k === "id_token") return v;
+ }
+ return null;
+}