mobile friendly Welcome page

pull/118/head
Jon Eugster 3 years ago
parent ae6ffa7d01
commit 1af343f14e

@ -48,14 +48,14 @@ export const PrivacyPolicy: React.FC = () => {
const handleOpen = () => setOpen(true) const handleOpen = () => setOpen(true)
const handleClose = () => setOpen(false) const handleClose = () => setOpen(false)
return ( return (
<span> <>
<div className="privacy" onClick={handleOpen} title="Privacy Policy &amp; Impressum"> <div className="privacy" onClick={handleOpen} title="Privacy Policy &amp; Impressum">
<FontAwesomeIcon icon={faShield} /> <FontAwesomeIcon icon={faShield} />
<p className="p1">legal</p> <p className="p1">legal</p>
<p className="p2">notes</p> <p className="p2">notes</p>
</div> </div>
{open ? <PrivacyPolicyPopup handleClose={handleClose} /> : null} {open ? <PrivacyPolicyPopup handleClose={handleClose} /> : null}
</span> </>
) )
} }

@ -115,7 +115,7 @@ svg .disabled {
height: 40px; height: 40px;
font-size: 25px; font-size: 25px;
border-radius: 20px; border-radius: 20px;
position: absolute; position: fixed;
right: 10px; right: 10px;
bottom: 10px; bottom: 10px;
display: flex; display: flex;
@ -230,3 +230,27 @@ svg .disabled {
text-decoration: underline dotted; text-decoration: underline dotted;
} }
.mobile-nav {
padding-top: .5em;
padding-bottom: .5em;
position:relative;
height: 3em;
}
.mobile-nav .btn-next, .mobile-nav .btn-previous {
position: absolute;
margin: 0;
}
.mobile-nav .btn-previous {
left: 0;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
.mobile-nav .btn-next {
right: 0;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}

@ -9,7 +9,7 @@ import cytoscape, { LayoutOptions } from 'cytoscape'
import klay from 'cytoscape-klay'; import klay from 'cytoscape-klay';
import './welcome.css' import './welcome.css'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faGlobe, faHome, faCircleInfo, faArrowRight, faArrowLeft, faShield, faRotateLeft } from '@fortawesome/free-solid-svg-icons' import { faGlobe, faBook, faHome, faCircleInfo, faArrowRight, faArrowLeft, faShield, faRotateLeft } from '@fortawesome/free-solid-svg-icons'
import { GameIdContext } from '../app'; import { GameIdContext } from '../app';
import { selectCompleted, selectDifficulty } from '../state/progress'; import { selectCompleted, selectDifficulty } from '../state/progress';
import { useGetGameInfoQuery, useLoadInventoryOverviewQuery } from '../state/api'; import { useGetGameInfoQuery, useLoadInventoryOverviewQuery } from '../state/api';
@ -19,6 +19,7 @@ import {PrivacyPolicy} from './privacy_policy';
import { Button } from './button'; import { Button } from './button';
import { Documentation, Inventory } from './inventory'; import { Documentation, Inventory } from './inventory';
import { store } from '../state/store'; import { store } from '../state/store';
import { useWindowDimensions } from '../window_width';
cytoscape.use( klay ); cytoscape.use( klay );
@ -59,7 +60,14 @@ function LevelIcon({ worldId, levelId, position, completed, available }) {
function Welcome() { function Welcome() {
const navigate = useNavigate(); const navigate = useNavigate();
const [mobileLayout, setModileLayout] = useState(false)
// TODO: Make mobileLayout be changeable in settings
// TODO: Handle resize Events
const {width, height} = useWindowDimensions()
const [mobileLayout, setModileLayout] = useState(width < 800)
/** Only for mobile layout */
const [pageNumber, setPageNumber] = useState(0)
const gameId = React.useContext(GameIdContext) const gameId = React.useContext(GameIdContext)
const gameInfo = useGetGameInfoQuery({game: gameId}) const gameInfo = useGetGameInfoQuery({game: gameId})
@ -184,13 +192,67 @@ function Welcome() {
let dx = bounds ? s*(bounds.x2 - bounds.x1) + 2*padding : null let dx = bounds ? s*(bounds.x2 - bounds.x1) + 2*padding : null
return <div className="app-content "> // TODO: Pack the three columns into components, so we dont need to
// copy them for mobile layout
return <div className="app-content">
{ gameInfo.isLoading? { gameInfo.isLoading?
<Box display="flex" alignItems="center" justifyContent="center" sx={{ height: "calc(100vh - 64px)" }}> <Box display="flex" alignItems="center" justifyContent="center" sx={{ height: "calc(100vh - 64px)" }}>
<CircularProgress /> <CircularProgress />
</Box> </Box>
: mobileLayout ? : mobileLayout ?
<></> (pageNumber == 0 ?
<div className="column">
<div className="mobile-nav">
<Button className="btn btn-previous" to="/" title="back to games selection">
<FontAwesomeIcon icon={faArrowLeft} />&nbsp;<FontAwesomeIcon icon={faGlobe} />
</Button>
<Button className="btn btn-next" to=""
title="show inventory" onClick={() => {setPageNumber(1)}}>
Game&nbsp;<FontAwesomeIcon icon={faArrowRight}/>
</Button>
</div>
<Typography variant="body1" component="div" className="welcome-text">
<Markdown>{gameInfo.data?.introduction}</Markdown>
</Typography>
</div>
: pageNumber == 1 ?
<div className="column">
<div className="mobile-nav">
<Button className="btn btn-previous" to=""
title="back to introduction" onClick={() => {setPageNumber(0)}}>
<FontAwesomeIcon icon={faArrowLeft}/>&nbsp;Intro
</Button>
<Button className="btn btn-next" to=""
title="show inventory" onClick={() => {setPageNumber(2)}}>
<FontAwesomeIcon icon={faBook}/>&nbsp;<FontAwesomeIcon icon={faArrowRight}/>
</Button>
</div>
<WorldSelectionMenu />
<svg xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink"
width={bounds ? `${ds * dx}` : ''}
viewBox={bounds ? `${s*bounds.x1 - padding} ${s*bounds.y1 - padding} ${dx} ${s*(bounds.y2 - bounds.y1) + 2 * padding}` : ''}
className="world-selection"
>
{svgElements}
</svg>
</div>
:
<div className="inventory-panel">
<div className="mobile-nav">
<Button className="btn btn-previous" to=""
title="back to introduction" onClick={() => {setPageNumber(1)}}>
<FontAwesomeIcon icon={faArrowLeft} />&nbsp;Game
</Button>
</div>
{<>
{inventoryDoc ?
<Documentation name={inventoryDoc.name} type={inventoryDoc.type} handleClose={closeInventoryDoc}/>
:
<Inventory levelInfo={inventory.data} openDoc={openInventoryDoc} enableAll={true}/>
}
</>}
</div>
)
: :
<Split className="welcome" minSize={0} snapOffset={200} sizes={[40, 35, 25]}> <Split className="welcome" minSize={0} snapOffset={200} sizes={[40, 35, 25]}>
<div className="column"> <div className="column">

@ -28,7 +28,7 @@
} }
/* Test for mobile `title`s */ /* Test for mobile `title`s */
@media (pointer: coarse), (hover: none) { /* @media (pointer: coarse), (hover: none) {
[title] { [title] {
position: relative; position: relative;
display: inline-flex; display: inline-flex;
@ -44,4 +44,4 @@
width: fit-content; width: fit-content;
padding: 3px; padding: 3px;
} }
} } */

@ -0,0 +1,21 @@
import {useState, useEffect} from 'react'
function getWindowDimensions() {
const {innerWidth: width, innerHeight: height } = window
return {width, height}
}
export function useWindowDimensions() {
const [windowDimensions, setWindowDimensions] = useState(getWindowDimensions())
useEffect(() => {
function handleResize() {
setWindowDimensions(getWindowDimensions())
}
window.addEventListener('resize', handleResize)
return () => window.removeEventListener('resize', handleResize)
}, [])
return windowDimensions
}
Loading…
Cancel
Save