Update 2025-04-13_16:27:10
This commit is contained in:
184
static/app.js
Normal file
184
static/app.js
Normal file
@ -0,0 +1,184 @@
|
||||
/*************************************************
|
||||
* MindVault - Random Credentials Starting Round *
|
||||
************************************************/
|
||||
let round = 2;
|
||||
let waitTime = 10;
|
||||
let inProgress = false;
|
||||
|
||||
let currentCredentials = {};
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
document.getElementById("submit-btn").onclick = submitCredentials;
|
||||
document.getElementById("help-btn").onclick = showHelpModal;
|
||||
document.getElementById("new-game-btn").onclick = startNewGame;
|
||||
|
||||
loadHighScores();
|
||||
fetchInitialCredentials();
|
||||
});
|
||||
|
||||
function fetchInitialCredentials() {
|
||||
fetch(`/generate/${round}`)
|
||||
.then(r => r.json())
|
||||
.then(creds => {
|
||||
currentCredentials = creds;
|
||||
|
||||
fetch('/submit', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({username: creds.username, password: creds.password, round})
|
||||
});
|
||||
feedback(`👤 ${creds.username}\n🔑 ${creds.password}\nMemorize & wait ${waitTime}s`, 'highlight');
|
||||
updatePlaceholders();
|
||||
|
||||
startCountdown(waitTime, () => {
|
||||
feedback('🔑 Now type your NEW credentials!', 'highlight');
|
||||
clearInputs();
|
||||
document.getElementById('field1').focus();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function submitCredentials() {
|
||||
if (inProgress) return;
|
||||
const user = document.getElementById('field1').value;
|
||||
const pass = document.getElementById('field2').value;
|
||||
|
||||
if (user.length !== round || pass.length !== round) {
|
||||
feedback(`❌ Enter exactly ${round} char(s)!`, 'failure');
|
||||
return;
|
||||
}
|
||||
|
||||
inProgress = true;
|
||||
|
||||
fetch('/login', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({username: user, password: pass, round})
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(data => {
|
||||
if (data.status === "success") {
|
||||
round++;
|
||||
waitTime++;
|
||||
|
||||
fetch(`/generate/${round}`)
|
||||
.then(r => r.json())
|
||||
.then(creds => {
|
||||
currentCredentials = creds;
|
||||
fetch('/submit', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({username: creds.username, password: creds.password, round})
|
||||
});
|
||||
|
||||
feedback(`🎉 Success! ✅ Round ${round - 1} coming up...
|
||||
👤 ${creds.username}
|
||||
🔑 ${creds.password}
|
||||
Memorize & wait ${waitTime}s`, 'highlight');
|
||||
|
||||
startCountdown(waitTime, () => {
|
||||
feedback('🔑 Now type your NEW credentials!', 'highlight');
|
||||
clearInputs();
|
||||
document.getElementById('field1').focus();
|
||||
inProgress = false;
|
||||
});
|
||||
});
|
||||
|
||||
updatePlaceholders();
|
||||
loadHighScores();
|
||||
} else {
|
||||
feedback('❌ Wrong credentials. Try again!', 'failure');
|
||||
inProgress = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function feedback(msg, status) {
|
||||
const el = document.getElementById('feedback');
|
||||
el.innerText = msg;
|
||||
el.className = status;
|
||||
}
|
||||
|
||||
function startCountdown(sec, cb) {
|
||||
const c = document.getElementById('countdown');
|
||||
let t = sec;
|
||||
c.innerText = `⏳ ${t}s`;
|
||||
const iv = setInterval(() => {
|
||||
t--;
|
||||
c.innerText = `⏳ ${t}s`;
|
||||
if (t <= 0) {
|
||||
clearInterval(iv);
|
||||
c.innerText = '';
|
||||
cb();
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
function clearInputs() {
|
||||
document.getElementById('field1').value = '';
|
||||
document.getElementById('field2').value = '';
|
||||
}
|
||||
|
||||
function updatePlaceholders() {
|
||||
const f1 = document.getElementById('field1');
|
||||
const f2 = document.getElementById('field2');
|
||||
f1.placeholder = `👤 (${round} char${round>1?'s':''})`;
|
||||
f2.placeholder = `🔑 (${round} char${round>1?'s':''})`;
|
||||
f1.maxLength = round;
|
||||
f2.maxLength = round;
|
||||
}
|
||||
|
||||
function loadHighScores() {
|
||||
fetch('/highscores')
|
||||
.then(r => r.json())
|
||||
.then(data => {
|
||||
const list = document.getElementById('score-list');
|
||||
list.innerHTML = '';
|
||||
data.highscores.forEach(([u, s]) => {
|
||||
const li = document.createElement('li');
|
||||
li.innerText = `${u} – Round ${s}`;
|
||||
list.appendChild(li);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function startNewGame() {
|
||||
round = 2;
|
||||
waitTime = 10;
|
||||
document.getElementById('round').innerText = round - 1;
|
||||
feedback(`🔄 New Game! Round 2, wait 10s`, 'highlight');
|
||||
clearInputs();
|
||||
updatePlaceholders();
|
||||
inProgress = false;
|
||||
|
||||
fetch('/newgame', {method:'POST'})
|
||||
.then(r => r.json())
|
||||
.then(d => {
|
||||
if (d.status === "cleared") loadHighScores();
|
||||
fetchInitialCredentials();
|
||||
});
|
||||
}
|
||||
|
||||
function showHelpModal() {
|
||||
document.getElementById('help-modal').classList.remove('hidden');
|
||||
}
|
||||
document.getElementById('close-modal').onclick = () => {
|
||||
document.getElementById('help-modal').classList.add('hidden');
|
||||
};
|
||||
window.onclick = (e) => {
|
||||
if (e.target.id === 'help-modal') {
|
||||
document.getElementById('help-modal').classList.add('hidden');
|
||||
}
|
||||
};
|
||||
window.onkeydown = (e) => {
|
||||
if (e.key === 'Escape') {
|
||||
document.getElementById('help-modal').classList.add('hidden');
|
||||
}
|
||||
if (e.key === 'Enter') {
|
||||
const modal = document.getElementById('help-modal');
|
||||
if (modal.classList.contains('hidden')) {
|
||||
document.getElementById("submit-btn").click();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
74
static/index.html
Normal file
74
static/index.html
Normal file
@ -0,0 +1,74 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>🧠 MindVault 🔐</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>🧠 MindVault 🔐</h1>
|
||||
|
||||
<div id="progress-info">📈 Round: <span id="round">1</span></div>
|
||||
|
||||
<input
|
||||
type="text"
|
||||
id="field1"
|
||||
name="field1"
|
||||
placeholder="👤"
|
||||
maxlength="1"
|
||||
autocomplete="off"
|
||||
autocorrect="off"
|
||||
autocapitalize="none"
|
||||
spellcheck="false"
|
||||
tabindex="1"
|
||||
>
|
||||
|
||||
<input
|
||||
type="text"
|
||||
id="field2"
|
||||
name="field2"
|
||||
placeholder="🔑"
|
||||
maxlength="1"
|
||||
autocomplete="off"
|
||||
autocorrect="off"
|
||||
autocapitalize="none"
|
||||
spellcheck="false"
|
||||
tabindex="2"
|
||||
>
|
||||
|
||||
<!-- Main action buttons -->
|
||||
<button id="submit-btn" tabindex="3">🚀 Submit Credentials</button>
|
||||
<button id="help-btn" tabindex="4">❓ Help</button>
|
||||
<button id="new-game-btn" tabindex="5">🔄 New Game</button>
|
||||
|
||||
<div id="feedback"></div>
|
||||
<div id="countdown"></div>
|
||||
|
||||
<div id="leaderboard">
|
||||
<h3>🏆 Top 10 Scores</h3>
|
||||
<ol id="score-list"></ol>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Help Modal -->
|
||||
<div id="help-modal" class="modal hidden">
|
||||
<div class="modal-content">
|
||||
<span id="close-modal">×</span>
|
||||
<h2>❓ How to Play MindVault 🧠🔐</h2>
|
||||
<p>
|
||||
1. Enter a username and password with the exact number of letters shown.<br>
|
||||
2. Click or press Enter on <strong>Submit Credentials</strong>.<br>
|
||||
3. Wait the specified time, then re-enter those same credentials to log in.<br>
|
||||
4. If successful 🎉, the next round adds +1 letter & +1 second wait.<br>
|
||||
5. Keep going to achieve the highest round possible! 📈✨<br><br>
|
||||
⚡ <em>Press ESC to close this window any time.</em>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="app.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
142
static/style.css
Normal file
142
static/style.css
Normal file
@ -0,0 +1,142 @@
|
||||
/* --- Global Styling --- */
|
||||
body {
|
||||
font-family: 'Arial', sans-serif;
|
||||
background-color: #ECF0F1;
|
||||
color: #34495E;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.container {
|
||||
background-color: #FFFFFF;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
||||
text-align: center;
|
||||
width: 340px;
|
||||
}
|
||||
|
||||
/* --- Input Fields --- */
|
||||
input {
|
||||
width: 90%;
|
||||
padding: 10px;
|
||||
margin: 10px 0;
|
||||
border: 2px solid #4A90E2;
|
||||
border-radius: 5px;
|
||||
font-size: 16px;
|
||||
text-align: center;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
input:focus {
|
||||
border-color: #F39C12;
|
||||
}
|
||||
|
||||
/* --- Buttons --- */
|
||||
button {
|
||||
background-color: #4A90E2;
|
||||
color: #FFFFFF;
|
||||
border: none;
|
||||
padding: 10px 15px;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
border-radius: 5px;
|
||||
transition: background-color 0.3s;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: #357ABD;
|
||||
}
|
||||
|
||||
/* Help Button */
|
||||
#help-btn {
|
||||
background-color: #F39C12;
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
#help-btn:hover {
|
||||
background-color: #D68910;
|
||||
}
|
||||
|
||||
/* --- Feedback and Countdown --- */
|
||||
#feedback {
|
||||
margin-top: 15px;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.success { color: #2ECC71; }
|
||||
.failure { color: #E74C3C; }
|
||||
.highlight { color: #F39C12; }
|
||||
|
||||
#countdown {
|
||||
margin-top: 10px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
/* --- Leaderboard --- */
|
||||
#leaderboard {
|
||||
margin-top: 20px;
|
||||
background-color: #F7F9FA;
|
||||
border-radius: 6px;
|
||||
padding: 10px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
#leaderboard h3 {
|
||||
color: #F39C12;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#score-list {
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
#score-list li {
|
||||
margin: 4px 0;
|
||||
color: #34495E;
|
||||
}
|
||||
|
||||
/* --- Help Modal --- */
|
||||
.modal {
|
||||
position: fixed;
|
||||
top: 0; left: 0;
|
||||
width: 100%; height: 100%;
|
||||
background-color: rgba(52, 73, 94, 0.8);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
display: inline-block; /* Helps size to content */
|
||||
width: auto; /* Let content define base width */
|
||||
min-width: 400px; /* Ensure it's not too narrow */
|
||||
max-width: 80%; /* Let it scale but keep within viewport */
|
||||
white-space: normal; /* Allows normal line wrapping */
|
||||
word-wrap: break-word; /* Avoid extremely long unbroken lines */
|
||||
background-color: #FFFFFF;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
text-align: left;
|
||||
position: relative;
|
||||
box-shadow: 0 4px 12px rgba(0,0,0,0.3);
|
||||
}
|
||||
|
||||
#close-modal {
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
right: 12px;
|
||||
color: #34495E;
|
||||
cursor: pointer;
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
Reference in New Issue
Block a user