## Major Changes ### Build System - Replace requirements.txt with pyproject.toml for modern dependency management - Support for uv package manager alongside pip - Update PyInstaller spec files for new dependencies and structure ### Desktop GUI (Tkinter → PySide6) - Complete rewrite of UI using PySide6/Qt6 - New modular structure in gui/ directory: - main_window.py: Main application window - macro_editor.py: Macro creation/editing dialog - command_builder.py: Visual command sequence builder - Modern dark theme with consistent styling - System tray integration ### Web Server (Flask → FastAPI) - Migrate from Flask/Waitress to FastAPI/Uvicorn - Add WebSocket support for real-time updates - Full CRUD API for macro management - Image upload endpoint ### Web Interface → PWA - New web/ directory with standalone static files - PWA manifest and service worker for installability - Offline caching support - Full macro editing from web interface - Responsive mobile-first design - Command builder UI matching desktop functionality ### Macro System Enhancement - New command sequence model replacing simple text/app types - Command types: text, key, hotkey, wait, app - Support for delays between commands (wait in ms) - Support for key presses between commands (enter, tab, etc.) - Automatic migration of existing macros to new format - Backward compatibility maintained ### Files Added - pyproject.toml - gui/__init__.py, main_window.py, macro_editor.py, command_builder.py - gui/widgets/__init__.py - web/index.html, manifest.json, service-worker.js - web/css/styles.css, web/js/app.js - web/icons/icon-192.png, icon-512.png ### Files Removed - requirements.txt (replaced by pyproject.toml) - ui_components.py (replaced by gui/ modules) - web_templates.py (replaced by web/ static files) - main.spec (consolidated into platform-specific specs) ### Files Modified - main.py: Simplified entry point for PySide6 - macro_manager.py: Command sequence model and migration - web_server.py: FastAPI implementation - config.py: Version bump to 0.9.0 - All .spec files: Updated for PySide6 and new structure - README.md: Complete rewrite for v0.9.0 - .gitea/workflows/release.yml: Disabled pending build testing 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
73 lines
2.3 KiB
JavaScript
73 lines
2.3 KiB
JavaScript
// MacroPad PWA Service Worker
|
|
const CACHE_NAME = 'macropad-v1';
|
|
const ASSETS_TO_CACHE = [
|
|
'/',
|
|
'/static/css/styles.css',
|
|
'/static/js/app.js',
|
|
'/static/icons/icon-192.png',
|
|
'/static/icons/icon-512.png',
|
|
'/manifest.json'
|
|
];
|
|
|
|
// Install event - cache assets
|
|
self.addEventListener('install', (event) => {
|
|
event.waitUntil(
|
|
caches.open(CACHE_NAME)
|
|
.then((cache) => {
|
|
console.log('Caching app assets');
|
|
return cache.addAll(ASSETS_TO_CACHE);
|
|
})
|
|
.then(() => self.skipWaiting())
|
|
);
|
|
});
|
|
|
|
// Activate event - clean old caches
|
|
self.addEventListener('activate', (event) => {
|
|
event.waitUntil(
|
|
caches.keys().then((cacheNames) => {
|
|
return Promise.all(
|
|
cacheNames
|
|
.filter((name) => name !== CACHE_NAME)
|
|
.map((name) => caches.delete(name))
|
|
);
|
|
}).then(() => self.clients.claim())
|
|
);
|
|
});
|
|
|
|
// Fetch event - serve from cache, fallback to network
|
|
self.addEventListener('fetch', (event) => {
|
|
const url = new URL(event.request.url);
|
|
|
|
// Always fetch API requests from network
|
|
if (url.pathname.startsWith('/api/') || url.pathname.startsWith('/ws')) {
|
|
event.respondWith(fetch(event.request));
|
|
return;
|
|
}
|
|
|
|
// For other requests, try cache first, then network
|
|
event.respondWith(
|
|
caches.match(event.request)
|
|
.then((response) => {
|
|
if (response) {
|
|
return response;
|
|
}
|
|
return fetch(event.request).then((networkResponse) => {
|
|
// Cache successful responses
|
|
if (networkResponse && networkResponse.status === 200) {
|
|
const responseClone = networkResponse.clone();
|
|
caches.open(CACHE_NAME).then((cache) => {
|
|
cache.put(event.request, responseClone);
|
|
});
|
|
}
|
|
return networkResponse;
|
|
});
|
|
})
|
|
.catch(() => {
|
|
// Return offline fallback for navigation requests
|
|
if (event.request.mode === 'navigate') {
|
|
return caches.match('/');
|
|
}
|
|
})
|
|
);
|
|
});
|