revision history WIP
This commit is contained in:
@@ -1,189 +1,190 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0"/>
|
||||
<title>Cuberoo</title>
|
||||
<link rel="stylesheet" href="style.css" />
|
||||
<!-- Add manifest and icons for PWA support -->
|
||||
<link rel="manifest" href="manifest.json">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-title" content="Cuberoo">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
||||
<link rel="apple-touch-icon" href="icon-192.png">
|
||||
<meta name="theme-color" content="#181818">
|
||||
</head>
|
||||
<body>
|
||||
<header class="header">
|
||||
<div class="logo">
|
||||
<img src="logo.png" alt="Logo" />
|
||||
<span>Cuberoo</span>
|
||||
</div>
|
||||
<!-- Sidebar toggle for mobile -->
|
||||
<button id="sidebarToggle" style="display:none;margin-left:16px;font-size:1.6em;background:none;border:none;color:#d103f9;z-index:1100;">☰</button>
|
||||
</header>
|
||||
<div class="container">
|
||||
<!-- wrapper for the draggable map class -->
|
||||
<div id="mapWrapper" class="map-wrapper">
|
||||
<!-- Settings button in top right -->
|
||||
<button id="settingsBtn" class="settings-btn" title="Settings">
|
||||
<span></span>
|
||||
</button>
|
||||
<!-- Settings menu (hidden by default) -->
|
||||
<div id="settingsMenu" class="settings-menu" style="display:none;">
|
||||
<div class="settings-menu-content">
|
||||
<!-- Square Style toggle -->
|
||||
<div style="margin-bottom:18px;">
|
||||
<label for="squareStyleToggle" style="color:white;vertical-align:middle;">Highlight by</label>
|
||||
<button id="squareStyleToggle" type="button" style="margin-left:10px;vertical-align:middle;"></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- class for the squares -->
|
||||
<div id="map" class="map"></div>
|
||||
<!-- zoom controls -->
|
||||
<div id="zoomControls">
|
||||
<button id="zoomIn">+</button>
|
||||
<button id="zoomOut">-</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- sidebar with the categories -->
|
||||
<div class="sidebar" id="sidebar">
|
||||
<!-- Categories will be dynamically loaded here -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// map layout. put numbers for the square IDs. null will be empty i guess.
|
||||
const mapData = [
|
||||
['1', '2', null, '13', '14'],
|
||||
['3', '4', null, '15', '16'],
|
||||
['5', '6', null, '17', '18'],
|
||||
['7', '8', null, '19', '20'],
|
||||
['9', '10', null, '21', '22'],
|
||||
['11', '12', null, '23', '24']
|
||||
];
|
||||
const mapEl = document.getElementById('map');
|
||||
mapData.forEach(row => {
|
||||
const rowEl = document.createElement('div');
|
||||
rowEl.classList.add('map-row');
|
||||
row.forEach(cell => {
|
||||
if (cell) {
|
||||
const squareEl = document.createElement('div');
|
||||
squareEl.classList.add('square');
|
||||
squareEl.dataset.squareId = cell;
|
||||
rowEl.appendChild(squareEl);
|
||||
} else {
|
||||
const emptyEl = document.createElement('div');
|
||||
emptyEl.classList.add('empty');
|
||||
rowEl.appendChild(emptyEl);
|
||||
}
|
||||
});
|
||||
mapEl.appendChild(rowEl);
|
||||
});
|
||||
|
||||
// Dynamically load categories and fruits
|
||||
async function loadCategories() {
|
||||
const sidebar = document.getElementById('sidebar');
|
||||
const res = await fetch('/api/categories');
|
||||
const categories = await res.json();
|
||||
sidebar.innerHTML = '';
|
||||
categories.forEach(cat => {
|
||||
const catDiv = document.createElement('div');
|
||||
catDiv.className = 'categories';
|
||||
catDiv.innerHTML = `
|
||||
<div class="category-header">
|
||||
<h4>${cat.name}</h4>
|
||||
<button class="category-toggle" type="button">▼</button>
|
||||
</div>
|
||||
<div class="category-content">
|
||||
${cat.fruits.map(fruit =>
|
||||
`<div class="fruit" draggable="true" data-fruit="${fruit}">${fruit}</div>`
|
||||
).join('')}
|
||||
</div>
|
||||
`;
|
||||
sidebar.appendChild(catDiv);
|
||||
});
|
||||
}
|
||||
loadCategories();
|
||||
|
||||
// Settings button/menu logic
|
||||
const settingsBtn = document.getElementById('settingsBtn');
|
||||
const settingsMenu = document.getElementById('settingsMenu');
|
||||
|
||||
settingsBtn.addEventListener('click', () => {
|
||||
settingsMenu.style.display = 'block';
|
||||
});
|
||||
// Optional: click outside menu closes it
|
||||
document.addEventListener('mousedown', (e) => {
|
||||
if (settingsMenu.style.display === 'block' &&
|
||||
!settingsMenu.contains(e.target) &&
|
||||
e.target !== settingsBtn) {
|
||||
settingsMenu.style.display = 'none';
|
||||
}
|
||||
});
|
||||
|
||||
// Filled/Outline setting logic (toggle)
|
||||
function applySquareStyle(style) {
|
||||
document.body.setAttribute('data-square-style', style);
|
||||
const btn = document.getElementById('squareStyleToggle');
|
||||
if (btn) {
|
||||
btn.textContent = style === 'filled' ? 'filling' : 'outlining';
|
||||
btn.className = style === 'filled' ? 'toggle-filled' : 'toggle-outline';
|
||||
}
|
||||
}
|
||||
function saveSquareStyle(style) {
|
||||
localStorage.setItem('squareStyle', style);
|
||||
}
|
||||
function loadSquareStyle() {
|
||||
return localStorage.getItem('squareStyle') || 'filled';
|
||||
}
|
||||
|
||||
function setupSquareStyleSetting() {
|
||||
const toggleBtn = document.getElementById('squareStyleToggle');
|
||||
if (!toggleBtn) return;
|
||||
let style = loadSquareStyle();
|
||||
applySquareStyle(style);
|
||||
toggleBtn.addEventListener('click', () => {
|
||||
style = (style === 'filled') ? 'outline' : 'filled';
|
||||
applySquareStyle(style);
|
||||
saveSquareStyle(style);
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', setupSquareStyleSetting);
|
||||
if (document.getElementById('squareStyleToggle')) setupSquareStyleSetting();
|
||||
|
||||
// Sidebar toggle for mobile
|
||||
function setupSidebarToggle() {
|
||||
const sidebar = document.getElementById('sidebar');
|
||||
const toggleBtn = document.getElementById('sidebarToggle');
|
||||
function updateSidebarDisplay() {
|
||||
if (window.innerWidth <= 900) {
|
||||
toggleBtn.style.display = '';
|
||||
sidebar.classList.remove('open');
|
||||
} else {
|
||||
toggleBtn.style.display = 'none';
|
||||
sidebar.classList.remove('open');
|
||||
}
|
||||
}
|
||||
toggleBtn.addEventListener('click', () => {
|
||||
sidebar.classList.toggle('open');
|
||||
});
|
||||
// Close sidebar when clicking outside on mobile
|
||||
document.addEventListener('mousedown', (e) => {
|
||||
if (window.innerWidth > 900) return;
|
||||
if (sidebar.classList.contains('open') && !sidebar.contains(e.target) && e.target !== toggleBtn) {
|
||||
sidebar.classList.remove('open');
|
||||
}
|
||||
});
|
||||
window.addEventListener('resize', updateSidebarDisplay);
|
||||
updateSidebarDisplay();
|
||||
}
|
||||
document.addEventListener('DOMContentLoaded', setupSidebarToggle);
|
||||
</script>
|
||||
<script src="/socket.io/socket.io.js"></script>
|
||||
<script src="script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0"/>
|
||||
<title>Cuberoo</title>
|
||||
<link rel="stylesheet" href="style.css" />
|
||||
<!-- Add manifest and icons for PWA support -->
|
||||
<link rel="manifest" href="manifest.json">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-title" content="Cuberoo">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
||||
<link rel="apple-touch-icon" href="icon-192.png">
|
||||
<meta name="theme-color" content="#181818">
|
||||
</head>
|
||||
<body>
|
||||
<header class="header">
|
||||
<div class="logo">
|
||||
<img src="logo.png" alt="Logo" />
|
||||
<span>Cuberoo</span>
|
||||
</div>
|
||||
<!-- Sidebar toggle for mobile -->
|
||||
<button id="sidebarToggle" style="display:none;margin-left:16px;font-size:1.6em;background:none;border:none;color:#d103f9;z-index:1100;">☰</button>
|
||||
<a href="history.html" style="margin-left:24px;color:#d103f9;font-weight:bold;text-decoration:none;font-size:1.1em;">History</a>
|
||||
</header>
|
||||
<div class="container">
|
||||
<!-- wrapper for the draggable map class -->
|
||||
<div id="mapWrapper" class="map-wrapper">
|
||||
<!-- Settings button in top right -->
|
||||
<button id="settingsBtn" class="settings-btn" title="Settings">
|
||||
<span></span>
|
||||
</button>
|
||||
<!-- Settings menu (hidden by default) -->
|
||||
<div id="settingsMenu" class="settings-menu" style="display:none;">
|
||||
<div class="settings-menu-content">
|
||||
<!-- Square Style toggle -->
|
||||
<div style="margin-bottom:18px;">
|
||||
<label for="squareStyleToggle" style="color:white;vertical-align:middle;">Highlight by</label>
|
||||
<button id="squareStyleToggle" type="button" style="margin-left:10px;vertical-align:middle;"></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- class for the squares -->
|
||||
<div id="map" class="map"></div>
|
||||
<!-- zoom controls -->
|
||||
<div id="zoomControls">
|
||||
<button id="zoomIn">+</button>
|
||||
<button id="zoomOut">-</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- sidebar with the categories -->
|
||||
<div class="sidebar" id="sidebar">
|
||||
<!-- Categories will be dynamically loaded here -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// map layout. put numbers for the square IDs. null will be empty i guess.
|
||||
const mapData = [
|
||||
['1', '2', null, '13', '14'],
|
||||
['3', '4', null, '15', '16'],
|
||||
['5', '6', null, '17', '18'],
|
||||
['7', '8', null, '19', '20'],
|
||||
['9', '10', null, '21', '22'],
|
||||
['11', '12', null, '23', '24']
|
||||
];
|
||||
const mapEl = document.getElementById('map');
|
||||
mapData.forEach(row => {
|
||||
const rowEl = document.createElement('div');
|
||||
rowEl.classList.add('map-row');
|
||||
row.forEach(cell => {
|
||||
if (cell) {
|
||||
const squareEl = document.createElement('div');
|
||||
squareEl.classList.add('square');
|
||||
squareEl.dataset.squareId = cell;
|
||||
rowEl.appendChild(squareEl);
|
||||
} else {
|
||||
const emptyEl = document.createElement('div');
|
||||
emptyEl.classList.add('empty');
|
||||
rowEl.appendChild(emptyEl);
|
||||
}
|
||||
});
|
||||
mapEl.appendChild(rowEl);
|
||||
});
|
||||
|
||||
// Dynamically load categories and fruits
|
||||
async function loadCategories() {
|
||||
const sidebar = document.getElementById('sidebar');
|
||||
const res = await fetch('/api/categories');
|
||||
const categories = await res.json();
|
||||
sidebar.innerHTML = '';
|
||||
categories.forEach(cat => {
|
||||
const catDiv = document.createElement('div');
|
||||
catDiv.className = 'categories';
|
||||
catDiv.innerHTML = `
|
||||
<div class="category-header">
|
||||
<h4>${cat.name}</h4>
|
||||
<button class="category-toggle" type="button">▼</button>
|
||||
</div>
|
||||
<div class="category-content">
|
||||
${cat.fruits.map(fruit =>
|
||||
`<div class="fruit" draggable="true" data-fruit="${fruit}">${fruit}</div>`
|
||||
).join('')}
|
||||
</div>
|
||||
`;
|
||||
sidebar.appendChild(catDiv);
|
||||
});
|
||||
}
|
||||
loadCategories();
|
||||
|
||||
// Settings button/menu logic
|
||||
const settingsBtn = document.getElementById('settingsBtn');
|
||||
const settingsMenu = document.getElementById('settingsMenu');
|
||||
|
||||
settingsBtn.addEventListener('click', () => {
|
||||
settingsMenu.style.display = 'block';
|
||||
});
|
||||
// Optional: click outside menu closes it
|
||||
document.addEventListener('mousedown', (e) => {
|
||||
if (settingsMenu.style.display === 'block' &&
|
||||
!settingsMenu.contains(e.target) &&
|
||||
e.target !== settingsBtn) {
|
||||
settingsMenu.style.display = 'none';
|
||||
}
|
||||
});
|
||||
|
||||
// Filled/Outline setting logic (toggle)
|
||||
function applySquareStyle(style) {
|
||||
document.body.setAttribute('data-square-style', style);
|
||||
const btn = document.getElementById('squareStyleToggle');
|
||||
if (btn) {
|
||||
btn.textContent = style === 'filled' ? 'filling' : 'outlining';
|
||||
btn.className = style === 'filled' ? 'toggle-filled' : 'toggle-outline';
|
||||
}
|
||||
}
|
||||
function saveSquareStyle(style) {
|
||||
localStorage.setItem('squareStyle', style);
|
||||
}
|
||||
function loadSquareStyle() {
|
||||
return localStorage.getItem('squareStyle') || 'filled';
|
||||
}
|
||||
|
||||
function setupSquareStyleSetting() {
|
||||
const toggleBtn = document.getElementById('squareStyleToggle');
|
||||
if (!toggleBtn) return;
|
||||
let style = loadSquareStyle();
|
||||
applySquareStyle(style);
|
||||
toggleBtn.addEventListener('click', () => {
|
||||
style = (style === 'filled') ? 'outline' : 'filled';
|
||||
applySquareStyle(style);
|
||||
saveSquareStyle(style);
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', setupSquareStyleSetting);
|
||||
if (document.getElementById('squareStyleToggle')) setupSquareStyleSetting();
|
||||
|
||||
// Sidebar toggle for mobile
|
||||
function setupSidebarToggle() {
|
||||
const sidebar = document.getElementById('sidebar');
|
||||
const toggleBtn = document.getElementById('sidebarToggle');
|
||||
function updateSidebarDisplay() {
|
||||
if (window.innerWidth <= 900) {
|
||||
toggleBtn.style.display = '';
|
||||
sidebar.classList.remove('open');
|
||||
} else {
|
||||
toggleBtn.style.display = 'none';
|
||||
sidebar.classList.remove('open');
|
||||
}
|
||||
}
|
||||
toggleBtn.addEventListener('click', () => {
|
||||
sidebar.classList.toggle('open');
|
||||
});
|
||||
// Close sidebar when clicking outside on mobile
|
||||
document.addEventListener('mousedown', (e) => {
|
||||
if (window.innerWidth > 900) return;
|
||||
if (sidebar.classList.contains('open') && !sidebar.contains(e.target) && e.target !== toggleBtn) {
|
||||
sidebar.classList.remove('open');
|
||||
}
|
||||
});
|
||||
window.addEventListener('resize', updateSidebarDisplay);
|
||||
updateSidebarDisplay();
|
||||
}
|
||||
document.addEventListener('DOMContentLoaded', setupSidebarToggle);
|
||||
</script>
|
||||
<script src="/socket.io/socket.io.js"></script>
|
||||
<script src="script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user