Add NextSnap PWA with photo gallery viewer and continuous capture
Offline-first photo capture app for Nextcloud with: - Camera capture with continuous mode (auto-reopens after each photo) - File browser with fullscreen image gallery, swipe navigation, and rename - Upload queue with background sync engine - Admin panel for Nextcloud user management - Service worker for offline-first caching (v13) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
102
app/templates/base.html
Normal file
102
app/templates/base.html
Normal file
@@ -0,0 +1,102 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||
|
||||
<!-- PWA Meta Tags -->
|
||||
<meta name="theme-color" content="#16213e">
|
||||
<link rel="manifest" href="{{ url_for('static', filename='manifest.json') }}">
|
||||
|
||||
<!-- iOS PWA Support -->
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
||||
<meta name="apple-mobile-web-app-title" content="NextSnap">
|
||||
<link rel="apple-touch-icon" href="{{ url_for('static', filename='icons/icon-192.png') }}">
|
||||
|
||||
<title>{% block title %}NextSnap{% endblock %}</title>
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
|
||||
{% block extra_css %}{% endblock %}
|
||||
</head>
|
||||
<body>
|
||||
<!-- Top Bar -->
|
||||
<header class="top-bar">
|
||||
<div class="top-bar-content">
|
||||
<h1 class="app-title">NextSnap</h1>
|
||||
<div class="top-bar-indicators">
|
||||
<div class="connectivity-indicator online" title="Online"></div>
|
||||
<div class="pending-count" id="pendingCount" style="display: none;">
|
||||
<span id="pendingCountValue">0</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- Main App Content -->
|
||||
<main id="app">
|
||||
{% block content %}{% endblock %}
|
||||
</main>
|
||||
|
||||
<!-- Bottom Navigation (for authenticated pages) -->
|
||||
{% if show_nav %}
|
||||
<nav class="bottom-nav">
|
||||
<a href="/capture" class="nav-item {% if request.path == '/capture' %}active{% endif %}">
|
||||
<span class="nav-icon">📷</span>
|
||||
<span class="nav-label">Capture</span>
|
||||
</a>
|
||||
<a href="/queue" class="nav-item {% if request.path == '/queue' %}active{% endif %}">
|
||||
<span class="nav-icon">📤</span>
|
||||
<span class="nav-label">Queue</span>
|
||||
</a>
|
||||
<a href="/browser" class="nav-item {% if request.path == '/browser' %}active{% endif %}">
|
||||
<span class="nav-icon">📁</span>
|
||||
<span class="nav-label">Files</span>
|
||||
</a>
|
||||
{% if is_admin %}
|
||||
<a href="/admin" class="nav-item {% if request.path == '/admin' %}active{% endif %}">
|
||||
<span class="nav-icon">⚙️</span>
|
||||
<span class="nav-label">Admin</span>
|
||||
</a>
|
||||
{% endif %}
|
||||
</nav>
|
||||
{% endif %}
|
||||
|
||||
<!-- Service Worker Registration -->
|
||||
<script>
|
||||
if ('serviceWorker' in navigator) {
|
||||
window.addEventListener('load', () => {
|
||||
navigator.serviceWorker.register('/static/sw.js')
|
||||
.then((registration) => {
|
||||
console.log('Service Worker registered:', registration.scope);
|
||||
|
||||
// Check for updates periodically
|
||||
setInterval(() => {
|
||||
registration.update();
|
||||
}, 60000); // Check every minute
|
||||
|
||||
// Handle updates
|
||||
registration.addEventListener('updatefound', () => {
|
||||
const newWorker = registration.installing;
|
||||
newWorker.addEventListener('statechange', () => {
|
||||
if (newWorker.state === 'installed' && navigator.serviceWorker.controller) {
|
||||
// New service worker available
|
||||
console.log('New service worker available');
|
||||
// Could show update notification here
|
||||
}
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Service Worker registration failed:', error);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
console.warn('Service Workers not supported in this browser');
|
||||
}
|
||||
</script>
|
||||
|
||||
<script src="{{ url_for('static', filename='js/app.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/polish.js') }}"></script>
|
||||
{% block extra_js %}{% endblock %}
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user