Merge pull request #26 from jhalitaksoy/feature/user-status
Feature/user status
This commit is contained in:
commit
b395c6974d
@ -27,7 +27,7 @@ const Button: FunctionComponent<{
|
|||||||
margin: 5px;
|
margin: 5px;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: 4vw;
|
border-radius: 30px;
|
||||||
}
|
}
|
||||||
`}</style>
|
`}</style>
|
||||||
{text}
|
{text}
|
||||||
|
|||||||
21
src/components/Center.tsx
Normal file
21
src/components/Center.tsx
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import { FunctionComponent } from 'react';
|
||||||
|
|
||||||
|
const Center: FunctionComponent = ({children}) => {
|
||||||
|
return (
|
||||||
|
<div className='center'>
|
||||||
|
{children}
|
||||||
|
<style jsx>{`
|
||||||
|
.center {
|
||||||
|
display: flex;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
`}</style>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Center;
|
||||||
22
src/components/CircularPanel.tsx
Normal file
22
src/components/CircularPanel.tsx
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import { FunctionComponent } from 'react';
|
||||||
|
|
||||||
|
const CircularPanel: FunctionComponent<{
|
||||||
|
color: string;
|
||||||
|
style?: React.CSSProperties
|
||||||
|
}> = (props) => {
|
||||||
|
return (
|
||||||
|
<div style={Object.assign({ background: props.color }, props.style)}>
|
||||||
|
<style jsx>{`
|
||||||
|
div {
|
||||||
|
padding: 10px 20px;
|
||||||
|
border-radius: 30px;
|
||||||
|
}
|
||||||
|
`}
|
||||||
|
</style>
|
||||||
|
{props.children}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CircularPanel;
|
||||||
@ -7,7 +7,7 @@ const FloatingPanel: FunctionComponent<{
|
|||||||
color: string;
|
color: string;
|
||||||
visible: boolean;
|
visible: boolean;
|
||||||
}> = (props) => {
|
}> = (props) => {
|
||||||
if(!props.visible) return <></>
|
if(props.visible === false) return <></>
|
||||||
return (
|
return (
|
||||||
<div style={{
|
<div style={{
|
||||||
backgroundColor: props.color,
|
backgroundColor: props.color,
|
||||||
@ -21,6 +21,7 @@ const FloatingPanel: FunctionComponent<{
|
|||||||
border-top-right-radius: 1vw;
|
border-top-right-radius: 1vw;
|
||||||
min-width: 10vw;
|
min-width: 10vw;
|
||||||
min-height: 1vw;
|
min-height: 1vw;
|
||||||
|
z-index: 100;
|
||||||
}
|
}
|
||||||
`}</style>
|
`}</style>
|
||||||
{props.children}
|
{props.children}
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import * as React from "react";
|
|||||||
import { FunctionComponent } from "react";
|
import { FunctionComponent } from "react";
|
||||||
import { Context } from "../context/context";
|
import { Context } from "../context/context";
|
||||||
import { getColorByBrightness } from "../util/ColorUtil";
|
import { getColorByBrightness } from "../util/ColorUtil";
|
||||||
|
import CircularPanel from "./CircularPanel";
|
||||||
|
|
||||||
function getInfoPanelTextByGameState(params: {
|
function getInfoPanelTextByGameState(params: {
|
||||||
context: Context;
|
context: Context;
|
||||||
@ -10,7 +11,6 @@ function getInfoPanelTextByGameState(params: {
|
|||||||
crashMessage?: string;
|
crashMessage?: string;
|
||||||
userKey?: string;
|
userKey?: string;
|
||||||
userKeyWhoLeave?: string;
|
userKeyWhoLeave?: string;
|
||||||
searchingOpponent: boolean;
|
|
||||||
}): string | undefined {
|
}): string | undefined {
|
||||||
const {
|
const {
|
||||||
context,
|
context,
|
||||||
@ -18,11 +18,8 @@ function getInfoPanelTextByGameState(params: {
|
|||||||
crashMessage,
|
crashMessage,
|
||||||
userKey,
|
userKey,
|
||||||
userKeyWhoLeave,
|
userKeyWhoLeave,
|
||||||
searchingOpponent,
|
|
||||||
} = params;
|
} = params;
|
||||||
if (searchingOpponent) {
|
if (crashMessage) {
|
||||||
return context.texts.SearchingOpponent + " " + context.texts.PleaseWait;
|
|
||||||
} else if (crashMessage) {
|
|
||||||
return context.texts.GameCrashed + " " + crashMessage;
|
return context.texts.GameCrashed + " " + crashMessage;
|
||||||
} else if (userKeyWhoLeave) {
|
} else if (userKeyWhoLeave) {
|
||||||
let message = context.texts.OpponentLeavesTheGame;
|
let message = context.texts.OpponentLeavesTheGame;
|
||||||
@ -50,44 +47,24 @@ function getInfoPanelTextByGameState(params: {
|
|||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
const InfoPanelContainer: FunctionComponent<{
|
|
||||||
context: Context;
|
|
||||||
color: string;
|
|
||||||
}> = (props) => {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
background: props.color
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<style jsx>{`
|
|
||||||
div {
|
|
||||||
padding: 1vw 2vw;
|
|
||||||
margin-top: 1vw;
|
|
||||||
border-radius: 10vw;
|
|
||||||
}
|
|
||||||
`}
|
|
||||||
</style>
|
|
||||||
{props.children}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const InfoPanel: FunctionComponent<{
|
const InfoPanel: FunctionComponent<{
|
||||||
context: Context;
|
context: Context;
|
||||||
game?: MancalaGame;
|
game?: MancalaGame;
|
||||||
crashMessage?: string;
|
crashMessage?: string;
|
||||||
userKey?: string;
|
userKey?: string;
|
||||||
userKeyWhoLeave?: string;
|
userKeyWhoLeave?: string;
|
||||||
searchingOpponent: boolean;
|
style?: React.CSSProperties;
|
||||||
|
visible?: boolean;
|
||||||
}> = ({
|
}> = ({
|
||||||
context,
|
context,
|
||||||
game,
|
game,
|
||||||
crashMessage,
|
crashMessage,
|
||||||
userKey,
|
userKey,
|
||||||
userKeyWhoLeave,
|
userKeyWhoLeave,
|
||||||
searchingOpponent,
|
style,
|
||||||
|
visible
|
||||||
}) => {
|
}) => {
|
||||||
|
if (visible === false) return <></>;
|
||||||
const isUserTurn = userKey ? game?.checkIsPlayerTurn(userKey) : false;
|
const isUserTurn = userKey ? game?.checkIsPlayerTurn(userKey) : false;
|
||||||
const containerColor = isUserTurn
|
const containerColor = isUserTurn
|
||||||
? context.themeManager.theme.playerTurnColor
|
? context.themeManager.theme.playerTurnColor
|
||||||
@ -102,16 +79,15 @@ const InfoPanel: FunctionComponent<{
|
|||||||
game,
|
game,
|
||||||
crashMessage,
|
crashMessage,
|
||||||
userKey,
|
userKey,
|
||||||
userKeyWhoLeave,
|
userKeyWhoLeave
|
||||||
searchingOpponent,
|
|
||||||
});
|
});
|
||||||
if (text) {
|
if (text) {
|
||||||
return (
|
return (
|
||||||
<InfoPanelContainer context={context} color={containerColor}>
|
<CircularPanel style={style} color={containerColor}>
|
||||||
<h4 style={{ margin: "0", color: textColor }}>
|
<h4 style={{ margin: "0", color: textColor }}>
|
||||||
{text}
|
{text}
|
||||||
</h4>
|
</h4>
|
||||||
</InfoPanelContainer>
|
</CircularPanel>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return (<div></div>)
|
return (<div></div>)
|
||||||
|
|||||||
10
src/components/Space.tsx
Normal file
10
src/components/Space.tsx
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import { FunctionComponent } from 'react';
|
||||||
|
|
||||||
|
const Space: FunctionComponent<{ width?: string, height?: string }> = ({ width, height }) => {
|
||||||
|
return (
|
||||||
|
<div style={{ width, height}}/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Space;
|
||||||
73
src/components/UserStatus.tsx
Normal file
73
src/components/UserStatus.tsx
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import { FunctionComponent } from 'react';
|
||||||
|
import { Context } from '../context/context';
|
||||||
|
import { User } from '../models/User';
|
||||||
|
import { getColorByBrightness } from '../util/ColorUtil';
|
||||||
|
import Space from './Space';
|
||||||
|
|
||||||
|
export type LayoutMode = "right" | "left";
|
||||||
|
|
||||||
|
const UserStatus: FunctionComponent<{
|
||||||
|
context: Context,
|
||||||
|
user: User,
|
||||||
|
layoutMode: LayoutMode,
|
||||||
|
visible?: boolean,
|
||||||
|
style?: React.CSSProperties
|
||||||
|
}> = ({ context, user, layoutMode, visible, style }) => {
|
||||||
|
if (visible === false) return <></>;
|
||||||
|
const textColorOnBoard = getColorByBrightness(
|
||||||
|
context.themeManager.theme.boardColor,
|
||||||
|
context.themeManager.theme.textColor,
|
||||||
|
context.themeManager.theme.textLightColor
|
||||||
|
);
|
||||||
|
return (
|
||||||
|
<div style={style} className={layoutMode === "right" ? "flex-rtl" : "flex-ltr"}>
|
||||||
|
<span style={{color: textColorOnBoard}} className="material-symbols-outlined icon" >
|
||||||
|
face_6
|
||||||
|
</span>
|
||||||
|
<Space width='5px' />
|
||||||
|
<span style={{color: textColorOnBoard}} className='text'>{user.isAnonymous ? context.texts.Anonymous : user.name}</span>
|
||||||
|
<Space width='5px' />
|
||||||
|
<div className={"circle " + (user.isOnline ? "online" : "offline")}></div>
|
||||||
|
<style jsx>{`
|
||||||
|
.online {
|
||||||
|
background-color: ${context.themeManager.theme.boardColor};
|
||||||
|
}
|
||||||
|
.offline {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
.circle {
|
||||||
|
width: 15px;
|
||||||
|
height: 15px;
|
||||||
|
min-width: 15px;
|
||||||
|
min-height: 15px;
|
||||||
|
border-radius: 15px;
|
||||||
|
border: 2px solid ${context.themeManager.theme.boardColor};
|
||||||
|
}
|
||||||
|
.flex-rtl {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row-reverse;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.flex-ltr {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.text {
|
||||||
|
font-weight: bold;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.icon {
|
||||||
|
color : "grey";
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
font-size: 32px;
|
||||||
|
}
|
||||||
|
`}</style>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default UserStatus;
|
||||||
22
src/components/board/BoardToolbar.tsx
Normal file
22
src/components/board/BoardToolbar.tsx
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import { FunctionComponent } from 'react';
|
||||||
|
|
||||||
|
const BoardToolbar: FunctionComponent<{ visible?: boolean, style?: React.CSSProperties }> = ({ children, visible, style }) => {
|
||||||
|
if(visible === false) return <></>;
|
||||||
|
return (
|
||||||
|
<div style={style} className='toolbar'>
|
||||||
|
{children}
|
||||||
|
<style jsx>{`
|
||||||
|
.toolbar {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-self: stretch;
|
||||||
|
}
|
||||||
|
`}</style>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default BoardToolbar;
|
||||||
@ -56,7 +56,6 @@ const BoardView: FunctionComponent<{
|
|||||||
{isPlayer2 ? player2Pits : player1Pits}
|
{isPlayer2 ? player2Pits : player1Pits}
|
||||||
<style jsx>{`
|
<style jsx>{`
|
||||||
.board {
|
.board {
|
||||||
margin: 1vw;
|
|
||||||
padding: 2vw;
|
padding: 2vw;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(8, 11vw);
|
grid-template-columns: repeat(8, 11vw);
|
||||||
|
|||||||
@ -8,3 +8,4 @@ export const channel_on_game_crashed = "on_game_crashed"
|
|||||||
export const channel_on_game_user_leave = "on_game_user_leave"
|
export const channel_on_game_user_leave = "on_game_user_leave"
|
||||||
export const channel_ping = "ping"
|
export const channel_ping = "ping"
|
||||||
export const channel_pong = "pong"
|
export const channel_pong = "pong"
|
||||||
|
export const channel_on_user_connection_change = "channel_on_user_connection_change"
|
||||||
@ -20,7 +20,8 @@ export type Texts = {
|
|||||||
YouLeftTheGame: string,
|
YouLeftTheGame: string,
|
||||||
SearchingOpponent: string,
|
SearchingOpponent: string,
|
||||||
PleaseWait : string,
|
PleaseWait : string,
|
||||||
GameDraw : string
|
GameDraw : string,
|
||||||
|
Anonymous: string,
|
||||||
}
|
}
|
||||||
|
|
||||||
export const EnUs: Texts = {
|
export const EnUs: Texts = {
|
||||||
@ -44,7 +45,8 @@ export const EnUs: Texts = {
|
|||||||
YouLeftTheGame: "You Left The Game",
|
YouLeftTheGame: "You Left The Game",
|
||||||
SearchingOpponent: "Searching Opponent",
|
SearchingOpponent: "Searching Opponent",
|
||||||
PleaseWait : "Please Wait",
|
PleaseWait : "Please Wait",
|
||||||
GameDraw : "Draw"
|
GameDraw : "Draw",
|
||||||
|
Anonymous: "Anonymous",
|
||||||
}
|
}
|
||||||
|
|
||||||
export const TrTr: Texts = {
|
export const TrTr: Texts = {
|
||||||
@ -68,5 +70,6 @@ export const TrTr: Texts = {
|
|||||||
YouLeftTheGame: "Sen Oyundan Ayrıldın",
|
YouLeftTheGame: "Sen Oyundan Ayrıldın",
|
||||||
SearchingOpponent: "Rakip Aranıyor",
|
SearchingOpponent: "Rakip Aranıyor",
|
||||||
PleaseWait: "Lütfen Bekleyin",
|
PleaseWait: "Lütfen Bekleyin",
|
||||||
GameDraw : "Berabere"
|
GameDraw : "Berabere",
|
||||||
|
Anonymous: "Anonim"
|
||||||
}
|
}
|
||||||
26
src/hooks/useWindowDimensions.ts
Normal file
26
src/hooks/useWindowDimensions.ts
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import { useState, useEffect } from 'react';
|
||||||
|
|
||||||
|
//https://stackoverflow.com/questions/36862334/get-viewport-window-height-in-reactjs
|
||||||
|
|
||||||
|
function getWindowDimensions() {
|
||||||
|
const { innerWidth: width, innerHeight: height } = window;
|
||||||
|
return {
|
||||||
|
width,
|
||||||
|
height
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function useWindowDimensions() {
|
||||||
|
const [windowDimensions, setWindowDimensions] = useState(getWindowDimensions());
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
function handleResize() {
|
||||||
|
setWindowDimensions(getWindowDimensions());
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener('resize', handleResize);
|
||||||
|
return () => window.removeEventListener('resize', handleResize);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return windowDimensions;
|
||||||
|
}
|
||||||
6
src/models/User.ts
Normal file
6
src/models/User.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
export interface User {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
isOnline: boolean;
|
||||||
|
isAnonymous: boolean;
|
||||||
|
}
|
||||||
4
src/models/UserConnectionInfo.ts
Normal file
4
src/models/UserConnectionInfo.ts
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
export interface UserConnectionInfo {
|
||||||
|
userId: string;
|
||||||
|
isOnline: boolean;
|
||||||
|
}
|
||||||
@ -10,6 +10,7 @@ import {
|
|||||||
channel_on_game_start,
|
channel_on_game_start,
|
||||||
channel_on_game_update,
|
channel_on_game_update,
|
||||||
channel_on_game_user_leave,
|
channel_on_game_user_leave,
|
||||||
|
channel_on_user_connection_change,
|
||||||
} from "../const/channel_names";
|
} from "../const/channel_names";
|
||||||
import InfoPanel from "../components/InfoPanel";
|
import InfoPanel from "../components/InfoPanel";
|
||||||
import { CommonMancalaGame, MancalaGame, Pit } from "mancala.js";
|
import { CommonMancalaGame, MancalaGame, Pit } from "mancala.js";
|
||||||
@ -19,7 +20,7 @@ import BoardViewModel from "../viewmodel/BoardViewModel";
|
|||||||
import { v4 } from "uuid";
|
import { v4 } from "uuid";
|
||||||
import { getColorByBrightness } from "../util/ColorUtil";
|
import { getColorByBrightness } from "../util/ColorUtil";
|
||||||
import { Theme } from "../theme/Theme";
|
import { Theme } from "../theme/Theme";
|
||||||
import HeaderBar from "../components/HeaderBar";
|
import HeaderBar from "../components/headerbar/HeaderBar";
|
||||||
import FloatingPanel from "../components/FloatingPanel";
|
import FloatingPanel from "../components/FloatingPanel";
|
||||||
import PageContainer from "../components/PageContainer";
|
import PageContainer from "../components/PageContainer";
|
||||||
import Row from "../components/Row";
|
import Row from "../components/Row";
|
||||||
@ -27,6 +28,12 @@ import HeaderbarIcon from "../components/headerbar/HeaderbarIcon";
|
|||||||
import HeaderbarTitle from "../components/headerbar/HeaderbarTitle";
|
import HeaderbarTitle from "../components/headerbar/HeaderbarTitle";
|
||||||
import ThemeSwitchMenu from "../components/headerbar/ThemeSwitchMenu";
|
import ThemeSwitchMenu from "../components/headerbar/ThemeSwitchMenu";
|
||||||
import Button from "../components/Button";
|
import Button from "../components/Button";
|
||||||
|
import BoardToolbar from "../components/board/BoardToolbar";
|
||||||
|
import UserStatus from "../components/UserStatus";
|
||||||
|
import Center from "../components/Center";
|
||||||
|
import CircularPanel from "../components/CircularPanel";
|
||||||
|
import useWindowDimensions from "../hooks/useWindowDimensions";
|
||||||
|
import { UserConnectionInfo } from "../models/UserConnectionInfo";
|
||||||
|
|
||||||
type ConnectionState = "connecting" | "error" | "connected" | "reconnecting";
|
type ConnectionState = "connecting" | "error" | "connected" | "reconnecting";
|
||||||
|
|
||||||
@ -56,6 +63,10 @@ const Home: FunctionComponent<{ initial?: number }> = ({ initial = 0 }) => {
|
|||||||
// We have to block future actions if there is an ongoing action.
|
// We have to block future actions if there is an ongoing action.
|
||||||
const [hasOngoingAction, setHasOngoingAction] = useState<boolean>(false);
|
const [hasOngoingAction, setHasOngoingAction] = useState<boolean>(false);
|
||||||
|
|
||||||
|
const { height, width } = useWindowDimensions();
|
||||||
|
|
||||||
|
const [isOpponentOnline, setIsOpponentOnline] = useState<boolean>(false);
|
||||||
|
|
||||||
const onConnectionDone = () => {
|
const onConnectionDone = () => {
|
||||||
setConnetionState("connected");
|
setConnetionState("connected");
|
||||||
};
|
};
|
||||||
@ -116,6 +127,12 @@ const Home: FunctionComponent<{ initial?: number }> = ({ initial = 0 }) => {
|
|||||||
setUserKeyWhoLeave(userKeyWhoLeave);
|
setUserKeyWhoLeave(userKeyWhoLeave);
|
||||||
setHasOngoingAction(false);
|
setHasOngoingAction(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
context.rtmt.listenMessage(channel_on_user_connection_change, (message: any) => {
|
||||||
|
const userConnectionInfo = message as UserConnectionInfo;
|
||||||
|
//todo: change this when implementing watch the game feature
|
||||||
|
setIsOpponentOnline(userConnectionInfo.isOnline);
|
||||||
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateBoardViewModel = (boardViewModel: BoardViewModel) => {
|
const updateBoardViewModel = (boardViewModel: BoardViewModel) => {
|
||||||
@ -137,6 +154,8 @@ const Home: FunctionComponent<{ initial?: number }> = ({ initial = 0 }) => {
|
|||||||
return index;
|
return index;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getOpponentId = () => game?.player1Id === userKey ? game?.player2Id : game?.player1Id;
|
||||||
|
|
||||||
const checkHasAnOngoingAction = () => hasOngoingAction;
|
const checkHasAnOngoingAction = () => hasOngoingAction;
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
@ -209,6 +228,12 @@ const Home: FunctionComponent<{ initial?: number }> = ({ initial = 0 }) => {
|
|||||||
context.themeManager.theme.textLightColor
|
context.themeManager.theme.textLightColor
|
||||||
);
|
);
|
||||||
const renderNewGameBtn = userKeyWhoLeave || !game || (game && game.state == "ended");
|
const renderNewGameBtn = userKeyWhoLeave || !game || (game && game.state == "ended");
|
||||||
|
const showBoardView = game && boardViewModel && userKey && true;
|
||||||
|
const opponentUser = { id: getOpponentId() || "0", name: "Anonymous", isOnline: isOpponentOnline, isAnonymous: true };
|
||||||
|
const user = { id: userKey || "1", name: "Anonymous", isOnline: connectionState === "connected", isAnonymous: true };
|
||||||
|
|
||||||
|
const isMobile = width < 600;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageContainer theme={theme!}>
|
<PageContainer theme={theme!}>
|
||||||
<FloatingPanel context={context} color={context.themeManager.theme.boardColor} visible={showConnectionState}>
|
<FloatingPanel context={context} color={context.themeManager.theme.boardColor} visible={showConnectionState}>
|
||||||
@ -228,14 +253,36 @@ const Home: FunctionComponent<{ initial?: number }> = ({ initial = 0 }) => {
|
|||||||
onClick={renderNewGameBtn ? onNewGameClick : onLeaveGameClick} />
|
onClick={renderNewGameBtn ? onNewGameClick : onLeaveGameClick} />
|
||||||
</Row>
|
</Row>
|
||||||
</HeaderBar>
|
</HeaderBar>
|
||||||
|
<BoardToolbar style={{ justifyContent: "center" }} visible={showBoardView && isMobile || false}>
|
||||||
<InfoPanel
|
<InfoPanel
|
||||||
|
style={{ marginTop: "0.5rem", marginBottom: "0.5rem" }}
|
||||||
|
context={context}
|
||||||
|
game={game}
|
||||||
|
crashMessage={crashMessage}
|
||||||
|
userKey={userKey}
|
||||||
|
userKeyWhoLeave={userKeyWhoLeave} />
|
||||||
|
</BoardToolbar>
|
||||||
|
<BoardToolbar style={{ alignItems: "flex-end" }} visible={showBoardView || false}>
|
||||||
|
<UserStatus style={{
|
||||||
|
marginBottom: "0.5rem", marginLeft: "6%", maxWidth: isMobile ? "40vw" : "30vw",
|
||||||
|
width: isMobile ? "40vw" : "30vw"
|
||||||
|
}} context={context} layoutMode="left" user={opponentUser} visible={showBoardView || false} />
|
||||||
|
<InfoPanel
|
||||||
|
style={{
|
||||||
|
marginTop: "0.5rem", marginBottom: "0.5rem",
|
||||||
|
}}
|
||||||
context={context}
|
context={context}
|
||||||
game={game}
|
game={game}
|
||||||
crashMessage={crashMessage}
|
crashMessage={crashMessage}
|
||||||
userKey={userKey}
|
userKey={userKey}
|
||||||
userKeyWhoLeave={userKeyWhoLeave}
|
userKeyWhoLeave={userKeyWhoLeave}
|
||||||
searchingOpponent={searchingOpponent} />
|
visible={!isMobile} />
|
||||||
{game && boardViewModel && userKey && (
|
<UserStatus style={{
|
||||||
|
marginBottom: "0.5rem", marginRight: "6%", maxWidth: isMobile ? "40vw" : "30vw",
|
||||||
|
width: isMobile ? "40vw" : "30vw"
|
||||||
|
}} context={context} layoutMode="right" user={user} visible={showBoardView || false} />
|
||||||
|
</BoardToolbar>
|
||||||
|
{showBoardView ? (
|
||||||
<BoardView
|
<BoardView
|
||||||
userKey={userKey}
|
userKey={userKey}
|
||||||
game={game}
|
game={game}
|
||||||
@ -243,6 +290,12 @@ const Home: FunctionComponent<{ initial?: number }> = ({ initial = 0 }) => {
|
|||||||
boardViewModel={boardViewModel}
|
boardViewModel={boardViewModel}
|
||||||
context={context}
|
context={context}
|
||||||
onPitSelect={onPitSelect} />
|
onPitSelect={onPitSelect} />
|
||||||
|
) : searchingOpponent && (
|
||||||
|
<Center>
|
||||||
|
<CircularPanel color={context.themeManager.theme.boardColor}>
|
||||||
|
<h4 style={{ margin: "0", color: textColorOnBoard }}>{`${context.texts.SearchingOpponent} ${context.texts.PleaseWait}...`}</h4>
|
||||||
|
</CircularPanel>
|
||||||
|
</Center>
|
||||||
)}
|
)}
|
||||||
</PageContainer>
|
</PageContainer>
|
||||||
);
|
);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user