Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 6 additions & 8 deletions src/components/flags/FlagsApi.js
Original file line number Diff line number Diff line change
Expand Up @@ -275,11 +275,8 @@ class FlagsApi extends React.Component {
}

return (
<div>
{/*// <Container style={{ 'display' : 'flex', 'justify-content' : 'center', width: '600px'}}>*/}
<Container fluid style={{ 'display' : 'flex', 'justify-content' : 'center'}}>

{/*<Toast show={true} style={{ width: '410px', margin: 'auto', marginTop: '10%' }}>*/}
<div className="game-wrapper">
<Container fluid className="game-container">
<Toast show={true} className="game-toast" onClose={this.redirect}>
<Toast.Header>
<strong className="mr-auto">Question:</strong>
Expand Down Expand Up @@ -314,7 +311,7 @@ class FlagsApi extends React.Component {
}
{this.state.paused && (
<div className="pause-overlay" onClick={this.togglePause}>
PAUSED - Click to Resume
PAUSED
</div>
)}
</div>
Expand Down Expand Up @@ -350,7 +347,7 @@ class FlagsApi extends React.Component {
{/*<button onClick={ () => this.submitScore(4)}>PEW</button>*/}

</Container>
<div style={{'display' : 'flex', 'margin-top' : '25px', 'justify-content' : 'center', 'gap' : '8px'}}>
<div className="game-buttons">
<Button variant="outline-secondary" onClick={() => this.exitGame()}>
QUIT
</Button>
Expand All @@ -361,8 +358,9 @@ class FlagsApi extends React.Component {
variant="outline-secondary"
onClick={this.togglePause}
disabled={this.props.lifes <= 0}
className="btn-pause"
>
{this.state.paused ? '▶ PLAY' : '❚❚ PAUSE'}
{this.state.paused ? '▶ RESUME' : '❚❚ PAUSE '}
</Button>
</div>
</div>
Expand Down
99 changes: 93 additions & 6 deletions src/components/flags/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,30 @@ body {
padding: 0!important;
}

/* Game wrapper and container */
.game-wrapper {
width: 100%;
min-height: 100vh;
}

.game-container {
display: flex;
justify-content: center;
width: 100%;
}

@media (max-width: 520px) {
.game-wrapper {
padding: 0;
margin: 0;
}

.game-container {
padding: 0 !important;
margin: 0 !important;
}
}

h1 {
color: red;
}
Expand Down Expand Up @@ -55,6 +79,13 @@ h1 {
max-width: 900px;
}

@media (max-width: 520px) {
.toast.game-toast {
max-width: none !important;
width: 100% !important;
}
}

/* Game area toast - responsive width */
.game-toast {
width: 100%;
Expand All @@ -65,9 +96,27 @@ h1 {

@media (max-width: 520px) {
.game-toast {
max-width: 100%;
width: 100%;
border-radius: 0;
max-width: 100% !important;
width: 100% !important;
border-radius: 0 !important;
margin: 0 !important;
border: none !important;
box-shadow: none !important;
flex-basis: 100% !important;
}

.game-toast.toast {
max-width: 100% !important;
}

.game-toast .toast-header {
border-radius: 0 !important;
}

.fade.toast.game-toast.show {
max-width: 100% !important;
width: 100% !important;
margin: 0 !important;
}
}

Expand All @@ -87,10 +136,24 @@ h1 {
padding-top: 0;
}

@media (max-width: 520px) {
.game-toast .toast-body {
padding: 0 !important;
}
}

div.container-fluid {
margin: 0;
padding: 0;
max-width: none;
margin: 0 !important;
padding: 0 !important;
max-width: none !important;
width: 100% !important;
}

@media (max-width: 520px) {
div.container-fluid {
padding-left: 0 !important;
padding-right: 0 !important;
}
}
div.col-12 {
max-width: 100%;
Expand Down Expand Up @@ -194,3 +257,27 @@ td:nth-of-type(2){
color: #6c757d;
cursor: pointer;
}

/* Game action buttons */
.game-buttons {
display: flex;
justify-content: center;
gap: 8px;
margin-top: 25px;
padding: 0 5px;
}

.game-buttons .btn-pause {
width: 120px;
}

@media (max-width: 520px) {
.game-buttons {
margin-top: 15px;
padding: 0 5px;
}

.game-buttons .btn-pause {
width: 120px;
}
}
44 changes: 36 additions & 8 deletions src/components/home/Home.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,28 @@ const Home = () => {
const { login: oauthLogin, isLoading } = useOAuth();
const history = useHistory();

// Check if animation should be shown (once per day)
const shouldShowAnimation = () => {
const lastAnimDate = localStorage.getItem('homeAnimationDate');
const today = new Date().toDateString();
if (lastAnimDate === today) {
return false;
}
return true;
};

const [skipAnimation] = useState(!shouldShowAnimation());

// Animation states
const [animPhase, setAnimPhase] = useState(0);
const [animPhase, setAnimPhase] = useState(skipAnimation ? 7 : 0);
// Phase 0: blank
// Phase 1: title visible
// Phase 2: description visible
// Phase 3: table slides in (blurred)
// Phase 4: "High Scores" bounces in
// Phase 5: rows unblur from bottom (except top)
// Phase 6: top scorer revealed + buttons visible
// Phase 6: buttons visible (top scorer still blurred)
// Phase 7: top scorer revealed
const [revealedRows, setRevealedRows] = useState([]);

const isTokenValid = () => {
Expand Down Expand Up @@ -72,6 +85,14 @@ const Home = () => {
useEffect(() => {
if (loading) return;

// Skip animation if already shown today
if (skipAnimation) {
// Reveal all rows immediately
const allRows = Array.from({ length: Math.min(leaderboard.length, 10) }, (_, i) => i);
setRevealedRows(allRows);
return;
}

const timers = [];

// Phase 1: Title appears (after 300ms)
Expand Down Expand Up @@ -99,15 +120,22 @@ const Home = () => {
}
}, 3600));

// Phase 6: Top scorer + buttons (after all rows revealed + pause)
// Phase 6: Buttons appear (after all rows revealed + pause, top scorer still blurred)
const totalRowDelay = Math.max(0, leaderboard.length - 1) * 200;
timers.push(setTimeout(() => {
setRevealedRows(prev => [...prev, 0]);
setAnimPhase(6);
}, 3600 + totalRowDelay + 1500));
}, 3600 + totalRowDelay + 1000));

// Phase 7: Top scorer revealed (after buttons appear)
timers.push(setTimeout(() => {
setRevealedRows(prev => [...prev, 0]);
setAnimPhase(7);
// Store today's date so animation won't show again today
localStorage.setItem('homeAnimationDate', new Date().toDateString());
}, 3600 + totalRowDelay + 1800));

return () => timers.forEach(t => clearTimeout(t));
}, [loading, leaderboard.length]);
}, [loading, leaderboard.length, skipAnimation]);

const handlePlay = () => {
history.push('/flagsapi');
Expand All @@ -130,7 +158,7 @@ const Home = () => {
};

return (
<div className={`page-wrapper ${animPhase < 6 ? 'animating' : ''}`}>
<div className={`page-wrapper ${animPhase < 7 ? 'animating' : ''}`}>
{/* Logout Confirmation Popup */}
{showLogoutPopup && (
<div className="popup-overlay" onClick={handleLogoutCancel}>
Expand Down Expand Up @@ -159,7 +187,7 @@ const Home = () => {
<Row className="mb-0">
<Col xs={12}>
<div className="home-hero">
{isLoggedIn && animPhase >= 6 && (
{isLoggedIn && animPhase >= 7 && (
<button
onClick={handleLogoutClick}
className="close-btn"
Expand Down