PWA, server needs to serve via HTTPS still

This commit is contained in:
Mario Zechner 2025-06-16 07:57:40 +02:00
parent 1d074e616b
commit 807b32d479
20 changed files with 258 additions and 0 deletions

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<browserconfig>
<msapplication>
<tile>
<square150x150logo src="/icons/icon-144x144.png"/>
<TileColor>#1e1e1e</TileColor>
</tile>
</msapplication>
</browserconfig>

BIN
web/public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

42
web/public/icons/icon.svg Normal file
View file

@ -0,0 +1,42 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<defs>
<linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#007acc;stop-opacity:1" />
<stop offset="100%" style="stop-color:#005a9e;stop-opacity:1" />
</linearGradient>
</defs>
<!-- Background -->
<rect width="512" height="512" rx="64" ry="64" fill="#1e1e1e"/>
<!-- Terminal window -->
<rect x="64" y="96" width="384" height="288" rx="16" ry="16" fill="#2d2d30" stroke="#007acc" stroke-width="2"/>
<!-- Terminal header -->
<rect x="64" y="96" width="384" height="48" rx="16" ry="16" fill="url(#grad1)"/>
<rect x="64" y="128" width="384" height="16" fill="url(#grad1)"/>
<!-- Window controls -->
<circle cx="96" cy="120" r="6" fill="#ff5f57"/>
<circle cx="120" cy="120" r="6" fill="#ffbd2e"/>
<circle cx="144" cy="120" r="6" fill="#28ca42"/>
<!-- Terminal content lines -->
<rect x="96" y="168" width="320" height="8" rx="4" fill="#007acc"/>
<rect x="96" y="188" width="280" height="8" rx="4" fill="#4fc1ff"/>
<rect x="96" y="208" width="300" height="8" rx="4" fill="#007acc"/>
<rect x="96" y="228" width="200" height="8" rx="4" fill="#4fc1ff"/>
<!-- Cursor -->
<rect x="224" y="248" width="12" height="16" fill="#00ff00" opacity="0.8"/>
<!-- Connection lines (representing tunnel/multiplexing) -->
<path d="M 256 400 Q 180 420 120 450" stroke="#007acc" stroke-width="4" fill="none" opacity="0.6"/>
<path d="M 256 400 Q 332 420 392 450" stroke="#007acc" stroke-width="4" fill="none" opacity="0.6"/>
<path d="M 256 400 Q 256 430 256 460" stroke="#007acc" stroke-width="4" fill="none" opacity="0.6"/>
<!-- Connection endpoints -->
<circle cx="120" cy="450" r="8" fill="#007acc"/>
<circle cx="256" cy="460" r="8" fill="#007acc"/>
<circle cx="392" cy="450" r="8" fill="#007acc"/>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View file

@ -4,8 +4,41 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>VibeTunnel - Terminal Multiplexer</title>
<meta name="description" content="Interactive terminal sessions in your browser with real-time streaming and mobile support">
<!-- PWA Manifest -->
<link rel="manifest" href="/manifest.json">
<!-- Theme colors -->
<meta name="theme-color" content="#007acc">
<meta name="msapplication-TileColor" content="#1e1e1e">
<meta name="msapplication-config" content="/browserconfig.xml">
<!-- Apple Touch Icons -->
<link rel="apple-touch-icon" sizes="152x152" href="/icons/icon-152x152.png">
<link rel="apple-touch-icon" sizes="180x180" href="/icons/icon-180x180.png">
<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="VibeTunnel">
<!-- Favicon -->
<link rel="icon" type="image/png" sizes="32x32" href="/icons/icon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/icons/icon-16x16.png">
<link rel="shortcut icon" href="/favicon.ico">
<!-- Open Graph / Social Media -->
<meta property="og:type" content="website">
<meta property="og:title" content="VibeTunnel - Terminal Multiplexer">
<meta property="og:description" content="Interactive terminal sessions in your browser with real-time streaming and mobile support">
<meta property="og:image" content="/icons/icon-512x512.png">
<meta property="og:url" content="/">
<meta name="twitter:card" content="summary_large_image">
<!-- Styles -->
<link rel="stylesheet" type="text/css" href="https://unpkg.com/asciinema-player@3.7.0/dist/bundle/asciinema-player.css" />
<link href="output.css" rel="stylesheet">
<!-- Import Maps -->
<script type="importmap">
{
"imports": {
@ -19,5 +52,76 @@
<vibetunnel-app></vibetunnel-app>
<script src="https://unpkg.com/asciinema-player@3.7.0/dist/bundle/asciinema-player.min.js"></script>
<script type="module" src="app-entry.js"></script>
<!-- Service Worker Registration -->
<script>
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/sw.js')
.then((registration) => {
console.log('PWA: Service Worker registered successfully:', registration.scope);
// Check for updates
registration.addEventListener('updatefound', () => {
const newWorker = registration.installing;
if (newWorker) {
newWorker.addEventListener('statechange', () => {
if (newWorker.state === 'installed' && navigator.serviceWorker.controller) {
// New update available
console.log('PWA: New version available');
// You could show a notification here to reload
}
});
}
});
})
.catch((error) => {
console.error('PWA: Service Worker registration failed:', error);
});
});
// Listen for messages from service worker
navigator.serviceWorker.addEventListener('message', (event) => {
if (event.data && event.data.type === 'CACHE_UPDATED') {
console.log('PWA: Cache updated');
}
});
}
// Handle install prompt
let deferredPrompt;
window.addEventListener('beforeinstallprompt', (e) => {
console.log('PWA: Install prompt available - you can install VibeTunnel!');
// Prevent Chrome 67 and earlier from automatically showing the prompt
e.preventDefault();
// Stash the event so it can be triggered later
deferredPrompt = e;
// Show a temporary notification that install is available
console.log('PWA: App can be installed - look for the install icon in your browser!');
// You can trigger the install prompt manually like this:
// deferredPrompt.prompt();
});
window.addEventListener('appinstalled', (evt) => {
console.log('PWA: App was installed successfully');
});
// Debug PWA readiness
window.addEventListener('load', () => {
// Check PWA criteria
console.log('PWA Debug Info:');
console.log('- HTTPS:', window.location.protocol === 'https:');
console.log('- Service Worker supported:', 'serviceWorker' in navigator);
console.log('- Manifest link present:', !!document.querySelector('link[rel="manifest"]'));
console.log('- Current URL:', window.location.href);
// Check if already installed
if (window.matchMedia && window.matchMedia('(display-mode: standalone)').matches) {
console.log('PWA: App is running in standalone mode (already installed)');
}
});
</script>
</body>
</html>

93
web/public/manifest.json Normal file
View file

@ -0,0 +1,93 @@
{
"name": "VibeTunnel",
"short_name": "VibeTunnel",
"description": "Interactive terminal sessions in your browser",
"start_url": "/",
"display": "standalone",
"background_color": "#1e1e1e",
"theme_color": "#007acc",
"orientation": "any",
"scope": "/",
"categories": ["developer", "utilities"],
"lang": "en-US",
"icons": [
{
"src": "/icons/icon-72x72.png",
"sizes": "72x72",
"type": "image/png",
"purpose": "any"
},
{
"src": "/icons/icon-96x96.png",
"sizes": "96x96",
"type": "image/png",
"purpose": "any"
},
{
"src": "/icons/icon-128x128.png",
"sizes": "128x128",
"type": "image/png",
"purpose": "any"
},
{
"src": "/icons/icon-144x144.png",
"sizes": "144x144",
"type": "image/png",
"purpose": "any"
},
{
"src": "/icons/icon-152x152.png",
"sizes": "152x152",
"type": "image/png",
"purpose": "any"
},
{
"src": "/icons/icon-192x192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "any"
},
{
"src": "/icons/icon-384x384.png",
"sizes": "384x384",
"type": "image/png",
"purpose": "any"
},
{
"src": "/icons/icon-512x512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "any"
}
],
"shortcuts": [
{
"name": "New Session",
"short_name": "New",
"description": "Create a new terminal session",
"url": "/?action=create",
"icons": [
{
"src": "/icons/icon-96x96.png",
"sizes": "96x96"
}
]
}
],
"screenshots": [
{
"src": "/screenshots/desktop.png",
"sizes": "1280x720",
"type": "image/png",
"form_factor": "wide",
"label": "VibeTunnel desktop view"
},
{
"src": "/screenshots/mobile.png",
"sizes": "390x844",
"type": "image/png",
"form_factor": "narrow",
"label": "VibeTunnel mobile view"
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View file

@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 720">
<!-- Desktop screenshot placeholder -->
<rect width="1280" height="720" fill="#1e1e1e"/>
<text x="640" y="360" text-anchor="middle" fill="#007acc" font-family="monospace" font-size="32">VibeTunnel Desktop View</text>
</svg>

After

Width:  |  Height:  |  Size: 293 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

View file

@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 390 844">
<!-- Mobile screenshot placeholder -->
<rect width="390" height="844" fill="#1e1e1e"/>
<text x="195" y="422" text-anchor="middle" fill="#007acc" font-family="monospace" font-size="16">VibeTunnel Mobile View</text>
</svg>

After

Width:  |  Height:  |  Size: 289 B