This commit is contained in:
Tommy Parnell
2020-04-08 19:10:05 -04:00
parent 62b2686a6d
commit 460a741c79
5 changed files with 74 additions and 38 deletions

10
src/models/Rooms.tsx Normal file
View File

@@ -0,0 +1,10 @@
import { ISpinnerItem } from "./Spinner";
export interface IRoom {
spinnerState: ISpinnerState
}
export interface ISpinnerState {
spinnerValue?: ISpinnerItem,
isSpinning: boolean
}

View File

@@ -1,35 +1,25 @@
export interface ISpinnerItem { export interface ISpinnerItem {
value: Number, value: Number,
color: "Black" | "Red", color: "Black" | "Red",
isMoneyCard?: Boolean; isMoneyCard?: boolean
toString: () => String;
} }
export class SpinnerItem implements ISpinnerItem { export function spinnerItemToString(item: ISpinnerItem) {
value: Number; return item.isMoneyCard ? `Money Card!` : `${item.value} ${item.color}`
color: "Black" | "Red";
isMoneyCard?: Boolean | undefined;
constructor(value: Number, color: "Black" | "Red", isMoneyCard?: Boolean) {
this.value = value;
this.color = color;
}
toString() {
return this.isMoneyCard ? `Money Card!` : `${this.value} ${this.color}`;
}
} }
export class Spinner { export class Spinner {
spinnerOptions: Array<ISpinnerItem> = [ spinnerOptions: Array<ISpinnerItem> = [
new SpinnerItem(4, "Black"), { value: 4, color: "Black" },
new SpinnerItem(2, "Red"), { value: 2, color: "Red" },
new SpinnerItem(1, "Black"), { value: 1, color: "Black" },
new SpinnerItem(3, "Red"), { value: 3, color: "Red" },
new SpinnerItem(5, "Black"), { value: 5, color: "Black" },
new SpinnerItem(2, "Red"), { value: 2, color: "Red" },
new SpinnerItem(4, "Black"), { value: 4, color: "Black" },
new SpinnerItem(3, "Red"), { value: 3, color: "Red" },
new SpinnerItem(1, "Black"), { value: 1, color: "Black" } ,
new SpinnerItem(5, "Red", true) { value: 5, color: "Red", isMoneyCard: true }
] ]
spin () { spin () {
return this.spinnerOptions[Math.floor(Math.random() * this.spinnerOptions.length)]; return this.spinnerOptions[Math.floor(Math.random() * this.spinnerOptions.length)];

View File

@@ -1,7 +1,11 @@
import React from 'react'; import React from 'react';
import { RouteComponentProps } from "@reach/router" import { RouteComponentProps, Link } from "@reach/router";
export function Home (props: RouteComponentProps) { export function Home (props: RouteComponentProps) {
return <h1>Home</h1> return (
<>
<h1>Home</h1>
<Link to="/room/1">Enter Game</Link>
</>
);
} }

View File

@@ -2,19 +2,33 @@ import React, { useState } from 'react';
import { RouteComponentProps } from "@reach/router" import { RouteComponentProps } from "@reach/router"
import Typography from '@material-ui/core/Typography'; import Typography from '@material-ui/core/Typography';
import { Spinner } from '../components/Spinner'; import { Spinner } from '../components/Spinner';
import { Spinner as SpinnerModel, ISpinnerItem } from "../models/Spinner"; import { Spinner as SpinnerModel, spinnerItemToString } from '../models/Spinner';
import { useDatabase } from '../store/firebase';
import { IRoom, ISpinnerState } from '../models/Rooms';
const spinnerSingleton = new SpinnerModel(); const spinnerSingleton = new SpinnerModel();
export function Room (props: RouteComponentProps<{id: Number}>) { export function Room ({ id }: RouteComponentProps<{id: Number}>) {
const [isSpinning, setIsSpinning] = useState<boolean>(false); // const [isSpinning, setIsSpinning] = useState<boolean>(false);
const [spinValue, setSpinValue] = useState<ISpinnerItem | null>(null); // const [spinValue, setSpinValue] = useState<ISpinnerItem | undefined>();
const [spinnerState, setSpinnerState] = useState<ISpinnerState>();
const ref = useDatabase<ISpinnerState>(`rooms/${id}/spinnerState`, (a) => {
if(!a) {
return;
}
setSpinnerState(a);
}, { isSpinning: false });
if(!id){
return <Typography variant="h1">Room not found 🔥</Typography>;
}
if(!spinnerState) {
return <Typography variant="h1">Loading...</Typography>;
}
return ( return (
<Spinner value={spinValue?.toString() || ""} isSpinning={isSpinning} onClick={ () => { <Spinner value={spinnerState?.spinnerValue ? spinnerItemToString(spinnerState.spinnerValue) : "Spin me"} isSpinning={!!spinnerState?.isSpinning} onClick={ () => {
setIsSpinning(true); ref.set({ ...spinnerState, isSpinning: true });
setTimeout(() => { setTimeout(() => {
setIsSpinning(false); ref.set({ isSpinning: false, spinnerValue: spinnerSingleton.spin() });
setSpinValue(spinnerSingleton.spin())
},1500); },1500);
}} /> }} />
); );

View File

@@ -1,4 +1,6 @@
import * as firebase from 'firebase'; import * as firebase from 'firebase';
import React, { useState, useEffect, useMemo } from 'react';
const config = { const config = {
apiKey: "AIzaSyD3Oh6tRozOmQg9pTc2-9UB4bwB1SQqUrY", apiKey: "AIzaSyD3Oh6tRozOmQg9pTc2-9UB4bwB1SQqUrY",
// authDomain: "retrod-7e2cd.firebaseapp.com", // authDomain: "retrod-7e2cd.firebaseapp.com",
@@ -6,3 +8,19 @@ const config = {
} }
firebase.initializeApp(config); firebase.initializeApp(config);
export const databaseRef = firebase.database(); export const databaseRef = firebase.database();
export function useDatabase<T>(ref: string, cb: (arg0: T | undefined) => void, defaultValue?: T ) {
const connectedRef = useMemo(() => databaseRef.ref(ref), [ref]);
useEffect(() => {
connectedRef.on('value', (snapshot) => {
const exists = snapshot.exists();
if(!exists && defaultValue) {
connectedRef.set(defaultValue);
}
cb(snapshot.val() as T);
});
return () => connectedRef.off('value');
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [connectedRef]);
return connectedRef;
}