diff --git a/web/css/styles.css b/web/css/styles.css
index 9d3959a..d5c5c10 100644
--- a/web/css/styles.css
+++ b/web/css/styles.css
@@ -550,3 +550,47 @@ body {
color: white;
padding: 0.5rem;
}
+
+/* Fullscreen Button */
+.header-btn.icon-btn {
+ padding: 0.5rem 0.75rem;
+ font-size: 1.2rem;
+ line-height: 1;
+}
+
+/* Wake Lock Status */
+.wake-lock-status {
+ display: flex;
+ align-items: center;
+ padding: 0.25rem 0.5rem;
+ border-radius: 4px;
+ font-size: 1rem;
+ opacity: 0.4;
+ transition: opacity 0.3s;
+}
+
+.wake-lock-status.active {
+ opacity: 1;
+}
+
+.wake-lock-status .wake-icon {
+ color: #ffc107;
+}
+
+.wake-lock-status.active .wake-icon {
+ animation: pulse-glow 2s ease-in-out infinite;
+}
+
+@keyframes pulse-glow {
+ 0%, 100% { opacity: 1; }
+ 50% { opacity: 0.6; }
+}
+
+/* Fullscreen styles */
+:fullscreen .header {
+ padding-top: 0.5rem;
+}
+
+:fullscreen .macro-grid {
+ padding-bottom: 1rem;
+}
diff --git a/web/index.html b/web/index.html
index 32db8da..7c50a6f 100644
--- a/web/index.html
+++ b/web/index.html
@@ -33,6 +33,10 @@
Disconnected
+
+ ☀
+
+
diff --git a/web/js/app.js b/web/js/app.js
index c79d76b..d22d4ee 100644
--- a/web/js/app.js
+++ b/web/js/app.js
@@ -6,6 +6,7 @@ class MacroPadApp {
this.tabs = [];
this.currentTab = 'All';
this.ws = null;
+ this.wakeLock = null;
this.init();
}
@@ -15,6 +16,7 @@ class MacroPadApp {
await this.loadMacros();
this.setupWebSocket();
this.setupEventListeners();
+ this.setupWakeLock();
this.checkInstallPrompt();
}
@@ -245,6 +247,58 @@ class MacroPadApp {
this.loadTabs();
this.loadMacros();
}
+
+ // Fullscreen
+ toggleFullscreen() {
+ if (!document.fullscreenElement) {
+ document.documentElement.requestFullscreen().catch(err => {
+ console.log('Fullscreen error:', err);
+ });
+ } else {
+ document.exitFullscreen();
+ }
+ }
+
+ // Wake Lock - prevents screen from sleeping
+ async setupWakeLock() {
+ if (!('wakeLock' in navigator)) {
+ console.log('Wake Lock API not supported');
+ document.getElementById('wake-lock-status')?.remove();
+ return;
+ }
+
+ // Request wake lock
+ await this.requestWakeLock();
+
+ // Re-acquire wake lock when page becomes visible again
+ document.addEventListener('visibilitychange', async () => {
+ if (document.visibilityState === 'visible') {
+ await this.requestWakeLock();
+ }
+ });
+ }
+
+ async requestWakeLock() {
+ try {
+ this.wakeLock = await navigator.wakeLock.request('screen');
+ this.updateWakeLockStatus(true);
+
+ this.wakeLock.addEventListener('release', () => {
+ this.updateWakeLockStatus(false);
+ });
+ } catch (err) {
+ console.log('Wake Lock error:', err);
+ this.updateWakeLockStatus(false);
+ }
+ }
+
+ updateWakeLockStatus(active) {
+ const status = document.getElementById('wake-lock-status');
+ if (status) {
+ status.classList.toggle('active', active);
+ status.title = active ? 'Screen will stay on' : 'Screen may sleep';
+ }
+ }
}
// Initialize app
diff --git a/web/service-worker.js b/web/service-worker.js
index 4aacc0e..d5b141c 100644
--- a/web/service-worker.js
+++ b/web/service-worker.js
@@ -1,5 +1,5 @@
// MacroPad PWA Service Worker
-const CACHE_NAME = 'macropad-v2';
+const CACHE_NAME = 'macropad-v3';
const ASSETS_TO_CACHE = [
'/',
'/static/css/styles.css',