Setup intro page + initialize repo
BIN
assets/cl_10.png
Normal file
After Width: | Height: | Size: 38 KiB |
BIN
assets/cl_11.png
Normal file
After Width: | Height: | Size: 174 KiB |
BIN
assets/cl_12.png
Normal file
After Width: | Height: | Size: 179 KiB |
BIN
assets/cl_13.png
Normal file
After Width: | Height: | Size: 158 KiB |
BIN
assets/cl_14.png
Normal file
After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
BIN
assets/cl_3.png
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
assets/cl_4.png
Normal file
After Width: | Height: | Size: 23 KiB |
BIN
assets/cl_5.png
Normal file
After Width: | Height: | Size: 27 KiB |
BIN
assets/cl_6.png
Normal file
After Width: | Height: | Size: 30 KiB |
BIN
assets/cl_7.png
Normal file
After Width: | Height: | Size: 31 KiB |
BIN
assets/cl_8.png
Normal file
After Width: | Height: | Size: 36 KiB |
BIN
assets/cl_9.png
Normal file
After Width: | Height: | Size: 37 KiB |
BIN
assets/di_10.png
Normal file
After Width: | Height: | Size: 30 KiB |
BIN
assets/di_11.png
Normal file
After Width: | Height: | Size: 178 KiB |
BIN
assets/di_12.png
Normal file
After Width: | Height: | Size: 183 KiB |
BIN
assets/di_13.png
Normal file
After Width: | Height: | Size: 168 KiB |
BIN
assets/di_14.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
assets/di_2.png
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
assets/di_3.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
assets/di_4.png
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
assets/di_5.png
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
assets/di_6.png
Normal file
After Width: | Height: | Size: 25 KiB |
BIN
assets/di_7.png
Normal file
After Width: | Height: | Size: 25 KiB |
BIN
assets/di_8.png
Normal file
After Width: | Height: | Size: 29 KiB |
BIN
assets/di_9.png
Normal file
After Width: | Height: | Size: 30 KiB |
BIN
assets/hr_10.png
Normal file
After Width: | Height: | Size: 29 KiB |
BIN
assets/hr_11.png
Normal file
After Width: | Height: | Size: 182 KiB |
BIN
assets/hr_12.png
Normal file
After Width: | Height: | Size: 190 KiB |
BIN
assets/hr_13.png
Normal file
After Width: | Height: | Size: 180 KiB |
BIN
assets/hr_14.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
assets/hr_2.png
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
assets/hr_3.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
assets/hr_4.png
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
assets/hr_5.png
Normal file
After Width: | Height: | Size: 23 KiB |
BIN
assets/hr_6.png
Normal file
After Width: | Height: | Size: 26 KiB |
BIN
assets/hr_7.png
Normal file
After Width: | Height: | Size: 26 KiB |
BIN
assets/hr_8.png
Normal file
After Width: | Height: | Size: 29 KiB |
BIN
assets/hr_9.png
Normal file
After Width: | Height: | Size: 29 KiB |
BIN
assets/sp_10.png
Normal file
After Width: | Height: | Size: 30 KiB |
BIN
assets/sp_11.png
Normal file
After Width: | Height: | Size: 178 KiB |
BIN
assets/sp_12.png
Normal file
After Width: | Height: | Size: 160 KiB |
BIN
assets/sp_13.png
Normal file
After Width: | Height: | Size: 176 KiB |
BIN
assets/sp_14.png
Normal file
After Width: | Height: | Size: 28 KiB |
BIN
assets/sp_2.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
assets/sp_3.png
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
assets/sp_4.png
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
assets/sp_5.png
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
assets/sp_6.png
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
assets/sp_7.png
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
assets/sp_8.png
Normal file
After Width: | Height: | Size: 29 KiB |
BIN
assets/sp_9.png
Normal file
After Width: | Height: | Size: 29 KiB |
BIN
assets/tassle.png
Normal file
After Width: | Height: | Size: 153 KiB |
@ -1,37 +1,42 @@
|
|||||||
// import firebase from 'firebase'
|
import firebase from 'firebase'
|
||||||
// import 'firebase/auth'
|
import 'firebase/auth'
|
||||||
|
|
||||||
// const app = firebase.initializeApp({
|
const app = firebase.initializeApp({
|
||||||
// // your-config-here
|
apiKey: "AIzaSyBICkyQIt-9lTsxHvRS1MOlZ-UdFVj8rsA",
|
||||||
// })
|
authDomain: "tomecraft-87ce5.firebaseapp.com",
|
||||||
|
projectId: "tomecraft-87ce5",
|
||||||
|
storageBucket: "tomecraft-87ce5.appspot.com",
|
||||||
|
messagingSenderId: "1021868917316",
|
||||||
|
appId: "1:1021868917316:web:6c58534dd0ed491beab211",
|
||||||
|
})
|
||||||
|
|
||||||
// const auth = app.auth()
|
const auth = app.auth()
|
||||||
|
|
||||||
// auto-login
|
// auto-login
|
||||||
// export function subscribeToAuthState(handleUser: (user: {uid: string; displayName: string} | null) => void) {
|
export function subscribeToAuthState(handleUser: (user: {uid: string; displayName: string} | null) => void) {
|
||||||
// return auth.onAuthStateChanged(handleUser)
|
return auth.onAuthStateChanged(handleUser)
|
||||||
// }
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Email/password
|
/// Email/password
|
||||||
///
|
///
|
||||||
|
|
||||||
// export async function registerBasic(email: string, password: string) {
|
export async function registerBasic(email: string, password: string) {
|
||||||
// const user = await auth.createUserWithEmailAndPassword(email, password)
|
const user = await auth.createUserWithEmailAndPassword(email, password)
|
||||||
// }
|
}
|
||||||
|
|
||||||
// export async function loginBasic(email: string, password: string): Promise<string | null> {
|
export async function loginBasic(email: string, password: string): Promise<string | null> {
|
||||||
// const credentials = await auth.signInWithEmailAndPassword(email, password)
|
const credentials = await auth.signInWithEmailAndPassword(email, password)
|
||||||
// return credentials.user?.uid ?? null
|
return credentials.user?.uid ?? null
|
||||||
// }
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Google
|
/// Google
|
||||||
///
|
///
|
||||||
|
|
||||||
// export async function loginGoogle(): Promise<string> {
|
export async function loginGoogle(): Promise<string> {
|
||||||
// // @ts-ignore deno does not recognize firebase.auth the way it is imported, but it exists
|
// @ts-ignore deno does not recognize firebase.auth the way it is imported, but it exists
|
||||||
// const provider = new firebase.auth.GoogleAuthProvider();
|
const provider = new firebase.auth.GoogleAuthProvider();
|
||||||
// const {accessToken, credential, user} = await auth.signInWithPopup(provider)
|
const {accessToken, credential, user} = await auth.signInWithPopup(provider)
|
||||||
// return user.uid
|
return user.uid
|
||||||
// }
|
}
|
||||||
|
34
client/components/IntroPage.tsx
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
import GithubIcon from './GithubIcon.tsx'
|
||||||
|
|
||||||
|
interface PageProps {
|
||||||
|
children: React.ReactNode
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function Page({children}: PageProps): JSX.Element {
|
||||||
|
return (
|
||||||
|
<div className="page">
|
||||||
|
<img className="tassle" src="assets/tassle.png" />
|
||||||
|
<div className="vertical-ribbon" />
|
||||||
|
<header className="intro-title-card-ribbon">
|
||||||
|
<div className="intro-title-ribbon">
|
||||||
|
<div className="into-title-container">
|
||||||
|
<h1 className="intro-title-text">
|
||||||
|
Tomecraft
|
||||||
|
</h1>
|
||||||
|
<a
|
||||||
|
href="https://github.com/sullivansean27/tomecraft"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
<GithubIcon size={80} />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<main className="intro-main">
|
||||||
|
{children}
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
@ -10,9 +10,9 @@ export default function Page({children}: PageProps): JSX.Element {
|
|||||||
return (
|
return (
|
||||||
<div className="page">
|
<div className="page">
|
||||||
<header className="header">
|
<header className="header">
|
||||||
<span className="header-text">
|
<h2 className="header-text">
|
||||||
Deno Web Starter
|
Tomecraft
|
||||||
</span>
|
</h2>
|
||||||
<a
|
<a
|
||||||
href="https://github.com/sullivansean27/deno-react-web-starter"
|
href="https://github.com/sullivansean27/deno-react-web-starter"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
|
2
client/game/Board.tsx
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
|
||||||
|
export default function Board() {}
|
57
client/game/Game.tsx
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
import React, { useEffect } from 'react'
|
||||||
|
import useWebSocket from 'react-use-websocket'
|
||||||
|
|
||||||
|
import {CardInstance} from './types.ts'
|
||||||
|
|
||||||
|
interface GameActionsContextValue {}
|
||||||
|
|
||||||
|
const GameActionsContext = React.createContext<GameActionsContextValue | null>(null)
|
||||||
|
|
||||||
|
interface GameClientState {
|
||||||
|
player_id: string
|
||||||
|
match_id: string
|
||||||
|
result: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface BoardPosition {
|
||||||
|
card: CardInstance | null
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PlayerBoard {
|
||||||
|
0: BoardPosition
|
||||||
|
1: BoardPosition
|
||||||
|
2: BoardPosition
|
||||||
|
3: BoardPosition
|
||||||
|
}
|
||||||
|
|
||||||
|
interface GameState {
|
||||||
|
self_board: PlayerBoard
|
||||||
|
self_hand: CardInstance[]
|
||||||
|
enemy_board: PlayerBoard
|
||||||
|
enemy_hand: CardInstance[]
|
||||||
|
}
|
||||||
|
|
||||||
|
interface GameProps {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function Game(props: GameProps): JSX.Element {
|
||||||
|
const [state, setState] = React.useState()
|
||||||
|
|
||||||
|
// ensure this is stable wrt state so that onMessage does not have to be constantly reattached
|
||||||
|
const onMessage = React.useCallback(() => {}, [])
|
||||||
|
|
||||||
|
const WS_URL = `ws://localhost:7636/ws`
|
||||||
|
const socket = useWebSocket(WS_URL, {onMessage})
|
||||||
|
useEffect(() => {
|
||||||
|
setInterval(() => console.log(socket.getWebSocket()), 3000)
|
||||||
|
}, [socket])
|
||||||
|
|
||||||
|
const gameActions = React.useMemo<GameActionsContextValue>(() => ({}), [socket.sendJsonMessage])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<GameActionsContext.Provider value={gameActions}>
|
||||||
|
<div />
|
||||||
|
</GameActionsContext.Provider>
|
||||||
|
)
|
||||||
|
}
|
28
client/game/cards/Card.tsx
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
import {CardKey, getCardSrc} from './cards.ts'
|
||||||
|
|
||||||
|
const EMPTY_SPACE = '-'
|
||||||
|
|
||||||
|
interface CardTokenProps {
|
||||||
|
cardKey: CardKey | null
|
||||||
|
onClick?: () => void
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function CardToken(props: CardTokenProps): JSX.Element {
|
||||||
|
const {onClick, cardKey} = props
|
||||||
|
|
||||||
|
if (cardKey == null) {
|
||||||
|
return (
|
||||||
|
<button>
|
||||||
|
<span>{EMPTY_SPACE}</span>
|
||||||
|
</button>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
const card = getCardSrc(cardKey)
|
||||||
|
return (
|
||||||
|
<button onClick={onClick}>
|
||||||
|
<img src={card} alt={cardKey} />
|
||||||
|
</button>
|
||||||
|
)
|
||||||
|
}
|
18
client/game/cards/Hand.tsx
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
import {CardInstance} from '../types.ts'
|
||||||
|
|
||||||
|
import Card from './Card.tsx'
|
||||||
|
|
||||||
|
interface HandProps {
|
||||||
|
cards: CardInstance[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function Hand(props: HandProps): JSX.Element {
|
||||||
|
const {cards} = props
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{cards.map((card) => <Card cardKey={card.key} />)}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
112
client/game/cards/cards.ts
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
export type CardKey =
|
||||||
|
| 'cl_2'
|
||||||
|
| 'cl_3'
|
||||||
|
| 'cl_4'
|
||||||
|
| 'cl_5'
|
||||||
|
| 'cl_6'
|
||||||
|
| 'cl_7'
|
||||||
|
| 'cl_8'
|
||||||
|
// | 'cl_9'
|
||||||
|
// | 'cl_10'
|
||||||
|
// | 'cl_11'
|
||||||
|
// | 'cl_12'
|
||||||
|
// | 'cl_13'
|
||||||
|
| 'cl_14'
|
||||||
|
| 'di_2'
|
||||||
|
| 'di_3'
|
||||||
|
| 'di_4'
|
||||||
|
| 'di_5'
|
||||||
|
| 'di_6'
|
||||||
|
| 'di_7'
|
||||||
|
| 'di_8'
|
||||||
|
// | 'di_9'
|
||||||
|
// | 'di_10'
|
||||||
|
// | 'di_11'
|
||||||
|
// | 'di_12'
|
||||||
|
// | 'di_13'
|
||||||
|
| 'di_14'
|
||||||
|
// | 'hr_2'
|
||||||
|
// | 'hr_3'
|
||||||
|
// | 'hr_4'
|
||||||
|
// | 'hr_5'
|
||||||
|
// | 'hr_6'
|
||||||
|
// | 'hr_7'
|
||||||
|
// | 'hr_8'
|
||||||
|
// | 'hr_9'
|
||||||
|
// | 'hr_10'
|
||||||
|
// | 'hr_11'
|
||||||
|
// | 'hr_12'
|
||||||
|
// | 'hr_13'
|
||||||
|
// | 'hr_14'
|
||||||
|
| 'sp_2'
|
||||||
|
| 'sp_3'
|
||||||
|
| 'sp_4'
|
||||||
|
| 'sp_5'
|
||||||
|
| 'sp_6'
|
||||||
|
| 'sp_7'
|
||||||
|
| 'sp_8'
|
||||||
|
// | 'sp_9'
|
||||||
|
// | 'sp_10'
|
||||||
|
// | 'sp_11'
|
||||||
|
// | 'sp_12'
|
||||||
|
// | 'sp_13'
|
||||||
|
| 'sp_14'
|
||||||
|
|
||||||
|
const cardPaths: Record<CardKey, string> = {
|
||||||
|
cl_2: 'cl_2.png',
|
||||||
|
cl_3: 'cl_3.png',
|
||||||
|
cl_4: 'cl_4.png',
|
||||||
|
cl_5: 'cl_5.png',
|
||||||
|
cl_6: 'cl_6.png',
|
||||||
|
cl_7: 'cl_7.png',
|
||||||
|
cl_8: 'cl_8.png',
|
||||||
|
// cl_9: 'cl_9.png',
|
||||||
|
// cl_10: 'cl_10.png',
|
||||||
|
// cl_11: 'cl_11.png',
|
||||||
|
// cl_12: 'cl_12.png',
|
||||||
|
// cl_13: 'cl_13.png',
|
||||||
|
cl_14: 'cl_14.png',
|
||||||
|
di_2: 'di_2.png',
|
||||||
|
di_3: 'di_3.png',
|
||||||
|
di_4: 'di_4.png',
|
||||||
|
di_5: 'di_5.png',
|
||||||
|
di_6: 'di_6.png',
|
||||||
|
di_7: 'di_7.png',
|
||||||
|
di_8: 'di_8.png',
|
||||||
|
// di_9: 'di_9.png',
|
||||||
|
// di_10: 'di_10.png',
|
||||||
|
// di_11: 'di_11.png',
|
||||||
|
// di_12: 'di_12.png',
|
||||||
|
// di_13: 'di_13.png',
|
||||||
|
di_14: 'di_14.png',
|
||||||
|
// hr_2: 'hr_2.png',
|
||||||
|
// hr_3: 'hr_3.png',
|
||||||
|
// hr_4: 'hr_4.png',
|
||||||
|
// hr_5: 'hr_5.png',
|
||||||
|
// hr_6: 'hr_6.png',
|
||||||
|
// hr_7: 'hr_7.png',
|
||||||
|
// hr_8: 'hr_8.png',
|
||||||
|
// hr_9: 'hr_9.png',
|
||||||
|
// hr_10: 'hr_10.png',
|
||||||
|
// hr_11: 'hr_11.png',
|
||||||
|
// hr_12: 'hr_12.png',
|
||||||
|
// hr_13: 'hr_13.png',
|
||||||
|
// hr_14: 'hr_14.png',
|
||||||
|
sp_2: 'sp_2.png',
|
||||||
|
sp_3: 'sp_3.png',
|
||||||
|
sp_4: 'sp_4.png',
|
||||||
|
sp_5: 'sp_5.png',
|
||||||
|
sp_6: 'sp_6.png',
|
||||||
|
sp_7: 'sp_7.png',
|
||||||
|
sp_8: 'sp_8.png',
|
||||||
|
// sp_9: 'sp_9.png',
|
||||||
|
// sp_10: 'sp_10.png',
|
||||||
|
// sp_11: 'sp_11.png',
|
||||||
|
// sp_12: 'sp_12.png',
|
||||||
|
// sp_13: 'sp_13.png',
|
||||||
|
sp_14: 'sp_14.png',
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getCardSrc(cardKey: CardKey): string {
|
||||||
|
return `/assets/${cardPaths[cardKey]}`
|
||||||
|
}
|
5
client/game/cards/getCardKey.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import {CardKey} from './cards.ts'
|
||||||
|
|
||||||
|
export default function getCardKey(suit: string, value: string): CardKey {
|
||||||
|
return `${suit}_${value}` as CardKey
|
||||||
|
}
|
6
client/game/types.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import {CardKey} from './cards/cards'
|
||||||
|
|
||||||
|
export interface CardInstance {
|
||||||
|
key: CardKey
|
||||||
|
// other relevant modifiers to show user
|
||||||
|
}
|
@ -1,14 +1,13 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
|
||||||
import Page from '../components/Page.tsx'
|
import IntroPage from '../components/IntroPage.tsx'
|
||||||
|
|
||||||
export default function AppPage() {
|
export default function AppPage() {
|
||||||
return (
|
return (
|
||||||
<Page>
|
<IntroPage>
|
||||||
<div>
|
<div>
|
||||||
<p>Hello world!</p>
|
<p>Hello world!</p>
|
||||||
<img style={{width: 100, height: 100}} src="/assets/example.png" />
|
|
||||||
</div>
|
</div>
|
||||||
</Page>
|
</IntroPage>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import GoogleButton from 'react-google-button'
|
import GoogleButton from 'react-google-button'
|
||||||
|
|
||||||
// import { loginGoogle } from '../api/auth.ts'
|
import { loginGoogle } from '../api/auth.ts'
|
||||||
import Page from '../components/Page.tsx'
|
import IntroPage from '../components/IntroPage.tsx'
|
||||||
|
|
||||||
// https://developers.google.com/identity/branding-guidelines
|
// https://developers.google.com/identity/branding-guidelines
|
||||||
// https://developers.google.com/identity/sign-in/web/sign-in
|
// https://developers.google.com/identity/sign-in/web/sign-in
|
||||||
function GoogleLoginButton() {
|
function GoogleLoginButton() {
|
||||||
const onClick = React.useCallback(async () => {
|
const onClick = React.useCallback(async () => {
|
||||||
// await loginGoogle()
|
await loginGoogle()
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -18,10 +18,10 @@ function GoogleLoginButton() {
|
|||||||
|
|
||||||
export default function LoginPage() {
|
export default function LoginPage() {
|
||||||
return (
|
return (
|
||||||
<Page>
|
<IntroPage>
|
||||||
<div>
|
<div>
|
||||||
<GoogleLoginButton />
|
<GoogleLoginButton />
|
||||||
</div>
|
</div>
|
||||||
</Page>
|
</IntroPage>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,100 @@
|
|||||||
|
h1 {
|
||||||
|
font-size: 3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
.page {
|
.page {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
|
font-family: sans-serif;
|
||||||
|
|
||||||
|
background-color: #ad9885;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Login and Intro pages */
|
||||||
|
|
||||||
|
.vertical-ribbon {
|
||||||
|
position: absolute;
|
||||||
|
right: 30%;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
width: 90px;
|
||||||
|
|
||||||
|
background-color: #d1345b;
|
||||||
|
box-shadow: -2px 2px 4px rgba(0, 0, 0, 0.25);
|
||||||
|
}
|
||||||
|
|
||||||
|
.intro-title-card-ribbon {
|
||||||
|
position: relative;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
top: 15%;
|
||||||
|
height: 240px;
|
||||||
|
|
||||||
|
background-color: #942911;
|
||||||
|
box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25);
|
||||||
|
}
|
||||||
|
|
||||||
|
.intro-title-ribbon {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
top: 2em;
|
||||||
|
bottom: 2em;
|
||||||
|
|
||||||
|
padding: 0 25%;
|
||||||
|
|
||||||
|
z-index: 1;
|
||||||
|
background-color: #3454d1;
|
||||||
|
box-shadow: 2px 8px 4px 1px rgba(0, 0, 0, 0.25);
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.into-title-container {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.intro-title-text {
|
||||||
|
color: #ddf6fd;
|
||||||
|
margin-right: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.intro-main {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 35%;
|
||||||
|
left: 30%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tassle {
|
||||||
|
position: absolute;
|
||||||
|
left: 5%;
|
||||||
|
top: 0;
|
||||||
|
z-index: 2;
|
||||||
|
|
||||||
|
width: 105px;
|
||||||
|
height: 415px;
|
||||||
|
|
||||||
|
object-fit: cover;
|
||||||
|
object-position: 0% 0%;
|
||||||
|
margin-top: -85px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Common pages */
|
||||||
|
|
||||||
.header {
|
.header {
|
||||||
height: 90px;
|
height: 90px;
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
|
@ -2,13 +2,12 @@ import React from 'react';
|
|||||||
|
|
||||||
import type { UserProfile } from '~/common/user.ts'
|
import type { UserProfile } from '~/common/user.ts'
|
||||||
|
|
||||||
// import { subscribeToAuthState } from './api/auth.ts'
|
import { subscribeToAuthState } from './api/auth.ts'
|
||||||
|
|
||||||
type AuthState =
|
type AuthState =
|
||||||
| {loginState: 'pending'}
|
| {loginState: 'pending'}
|
||||||
| {loginState: 'logged-out'}
|
| {loginState: 'logged-out'}
|
||||||
// | {loginState: 'logged-in'; userId: string; profile: UserProfile}
|
| {loginState: 'logged-in'; profile: UserProfile}
|
||||||
| {loginState: 'logged-in'; profile: {}}
|
|
||||||
type UserHandle = AuthState
|
type UserHandle = AuthState
|
||||||
|
|
||||||
const AuthContext = React.createContext<UserHandle | null>(null)
|
const AuthContext = React.createContext<UserHandle | null>(null)
|
||||||
@ -20,7 +19,7 @@ export function useAuth(): UserHandle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: UPDATE HERE TO ENABLE AUTH
|
// TODO: UPDATE HERE TO ENABLE AUTH
|
||||||
const initialAuthState: AuthState = {loginState: 'logged-in', profile: {}}
|
const initialAuthState: AuthState = {loginState: 'pending'}
|
||||||
|
|
||||||
interface AuthProviderProps {
|
interface AuthProviderProps {
|
||||||
children: React.ReactNode
|
children: React.ReactNode
|
||||||
@ -38,12 +37,15 @@ export function AuthProvider({children}: AuthProviderProps): JSX.Element {
|
|||||||
const [authState, setAuthState] = React.useState<AuthState>(initialAuthState)
|
const [authState, setAuthState] = React.useState<AuthState>(initialAuthState)
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
// subscribeToAuthState((user) => {
|
subscribeToAuthState((user) => {
|
||||||
// if (user) {
|
if (user) {
|
||||||
// setAuthState({ loginState: 'logged-in'})
|
setAuthState({
|
||||||
// }
|
loginState: 'logged-in',
|
||||||
// else setAuthState({ loginState: 'logged-out' })
|
profile: {displayName: user.displayName.split(' ')[0]},
|
||||||
// })
|
})
|
||||||
|
}
|
||||||
|
else setAuthState({ loginState: 'logged-out' })
|
||||||
|
})
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -62,7 +64,7 @@ export function useUser(): UserProfile {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface UserProviderProps {
|
interface UserProviderProps {
|
||||||
profile: {}
|
profile: UserProfile
|
||||||
children: React.ReactNode
|
children: React.ReactNode
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,15 +1,8 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import ReactDOM from 'react-dom'
|
import ReactDOM from 'react-dom'
|
||||||
|
|
||||||
//// import any necessary wasm file here
|
|
||||||
// import initWasm from '~/common/wasm/wasm_chess.js'
|
|
||||||
|
|
||||||
import App from '~/client/App.tsx'
|
import App from '~/client/App.tsx'
|
||||||
|
|
||||||
//// init wasm file here
|
|
||||||
//// fetch file contents from webserver so browser has access
|
|
||||||
// initWasm(fetch('wasm_chess.wasm'))
|
|
||||||
|
|
||||||
window.addEventListener('load', (event) => {
|
window.addEventListener('load', (event) => {
|
||||||
ReactDOM.hydrate(<App />, document.getElementById('root'))
|
ReactDOM.render(<App />, document.getElementById('root'))
|
||||||
})
|
})
|
||||||
|
@ -57,7 +57,6 @@ const html = `
|
|||||||
<body>
|
<body>
|
||||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||||
<div id="root">
|
<div id="root">
|
||||||
${ /* ReactDOMServer.renderToString(<App />) */ '' }
|
|
||||||
</div>
|
</div>
|
||||||
<script src="/bundle.js"></script>
|
<script src="/bundle.js"></script>
|
||||||
</body>
|
</body>
|
||||||
@ -72,14 +71,6 @@ staticRouter
|
|||||||
.get('/', (ctx) => {
|
.get('/', (ctx) => {
|
||||||
ctx.response.body = html
|
ctx.response.body = html
|
||||||
})
|
})
|
||||||
// // serve wasm file
|
|
||||||
// .get('/wasm.wasm', async (ctx) => {
|
|
||||||
// const headers = new Headers(ctx.response.headers)
|
|
||||||
// headers.set('Content-Type', 'application/wasm')
|
|
||||||
// ctx.response.headers = headers
|
|
||||||
// const body = await Deno.readFile('common/wasm/wasm_bg.wasm')
|
|
||||||
// ctx.response.body = body
|
|
||||||
// })
|
|
||||||
.get('/styles.css', (ctx) => {
|
.get('/styles.css', (ctx) => {
|
||||||
const styles = Deno.readTextFileSync('client/styles.css')
|
const styles = Deno.readTextFileSync('client/styles.css')
|
||||||
const contentTypeValue = contentType('styles.css')
|
const contentTypeValue = contentType('styles.css')
|
||||||
|
@ -40,12 +40,6 @@ app.use((context) => {
|
|||||||
context.response.body = `"${context.request.url}" not found`
|
context.response.body = `"${context.request.url}" not found`
|
||||||
})
|
})
|
||||||
|
|
||||||
//// init wasm file here
|
|
||||||
//// https://deno.com/deploy/docs/serve-static-assets
|
|
||||||
// const WASM_PATH = new URL('../common/wasm/wasm_bg.wasm', import.meta.url)
|
|
||||||
//// https://github.com/rustwasm/wasm-pack/issues/672#issuecomment-813630435
|
|
||||||
// await init(Deno.readFile(WASM_PATH))
|
|
||||||
|
|
||||||
const port = +(Deno.env.get('PORT') ?? 8080)
|
const port = +(Deno.env.get('PORT') ?? 8080)
|
||||||
console.log(`Listening on port ${port}...`)
|
console.log(`Listening on port ${port}...`)
|
||||||
app.listen(`:${port}`)
|
app.listen(`:${port}`)
|
||||||
|