Skip to content

Commit 29ec05b

Browse files
committed
feat: Add PWA support with installable app and offline capabilities
- Add vite-plugin-pwa with comprehensive service worker configuration - Create manifest.json with app metadata and icons - Implement offline splash page with retry functionality - Add PWA meta tags and icons for all platforms - Configure smart caching for PeerJS and QR services - Add auto-update notifications and service worker registration - Create comprehensive PWA installation documentation - Update README with PWA features and installation steps - Add icon generator tool for creating app icons Features: Installable on iOS, Android, and Desktop Offline support with custom splash page Auto-updates with user notifications App-like standalone experience Smart caching for better performance Cross-platform compatibility
1 parent eb0ad68 commit 29ec05b

17 files changed

+627
-7
lines changed

PWA_INSTALLATION.md

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
# PWA Installation Guide
2+
3+
PeerChat is now a Progressive Web App (PWA)! This means you can install it on your device and use it like a native app.
4+
5+
## 🚀 Installation Steps
6+
7+
### 📱 **Android (Chrome/Edge)**
8+
9+
1. **Open the app** in Chrome or Edge browser
10+
2. **Look for the install prompt** - You'll see a banner at the bottom saying "Add PeerChat to Home screen"
11+
3. **Tap "Add"** or "Install" when prompted
12+
4. **Alternative method**:
13+
- Tap the **three dots menu** (⋮) in the browser
14+
- Select **"Add to Home screen"** or **"Install app"**
15+
- Tap **"Add"** to confirm
16+
17+
### 🍎 **iOS (Safari)**
18+
19+
1. **Open the app** in Safari browser
20+
2. **Tap the Share button** (square with arrow pointing up)
21+
3. **Scroll down** and tap **"Add to Home Screen"**
22+
4. **Customize the name** if desired (default: "PeerChat")
23+
5. **Tap "Add"** in the top right corner
24+
25+
### 💻 **Desktop (Chrome/Edge/Firefox)**
26+
27+
#### Chrome/Edge:
28+
1. **Open the app** in Chrome or Edge
29+
2. **Look for the install icon** (⊕) in the address bar
30+
3. **Click the install icon** or look for "Install PeerChat" in the menu
31+
4. **Click "Install"** when prompted
32+
33+
#### Firefox:
34+
1. **Open the app** in Firefox
35+
2. **Click the three lines menu** (☰)
36+
3. **Select "Install"** from the menu
37+
4. **Click "Allow"** when prompted
38+
39+
## ✨ PWA Features
40+
41+
### **What You Get:**
42+
- 🏠 **App-like experience** - No browser UI, full screen
43+
- 📱 **Home screen icon** - Quick access from your device
44+
-**Faster loading** - Cached for offline use
45+
- 🔄 **Auto-updates** - Always get the latest version
46+
- 📶 **Offline support** - Works without internet (limited features)
47+
48+
### **Offline Capabilities:**
49+
- View previous chat history
50+
- Access app settings
51+
- Local P2P connections (same network)
52+
- Browse cached content
53+
54+
## 🛠️ Technical Details
55+
56+
### **Service Worker Features:**
57+
- **Auto-update**: App updates automatically in the background
58+
- **Offline fallback**: Shows offline page when no internet
59+
- **Smart caching**: Caches PeerJS and QR code services
60+
- **Background sync**: Syncs when connection is restored
61+
62+
### **Manifest Features:**
63+
- **Standalone display**: Runs like a native app
64+
- **Theme colors**: Matches your app's dark theme
65+
- **App shortcuts**: Quick access to voice chat
66+
- **Multiple icon sizes**: Optimized for all devices
67+
68+
## 🔧 Troubleshooting
69+
70+
### **Installation Issues:**
71+
72+
**Android:**
73+
- Make sure you're using Chrome or Edge
74+
- Check if "Add to Home screen" is enabled in browser settings
75+
- Try refreshing the page and trying again
76+
77+
**iOS:**
78+
- Must use Safari (not Chrome or other browsers)
79+
- iOS 11.3+ required for PWA support
80+
- Make sure JavaScript is enabled
81+
82+
**Desktop:**
83+
- Chrome 68+, Edge 79+, or Firefox 58+ required
84+
- Make sure the site is served over HTTPS
85+
- Check if pop-ups are blocked
86+
87+
### **App Not Working Offline:**
88+
- Clear browser cache and reinstall
89+
- Check if service worker is registered (DevTools > Application > Service Workers)
90+
- Make sure you're not in private/incognito mode
91+
92+
### **Updates Not Working:**
93+
- Force refresh the page (Ctrl+F5 or Cmd+Shift+R)
94+
- Clear app data and reinstall
95+
- Check browser console for service worker errors
96+
97+
## 📋 Requirements
98+
99+
### **Browser Support:**
100+
- ✅ Chrome 68+ (Android, Desktop)
101+
- ✅ Edge 79+ (Android, Desktop)
102+
- ✅ Safari 11.3+ (iOS, macOS)
103+
- ✅ Firefox 58+ (Desktop)
104+
- ❌ Internet Explorer (not supported)
105+
106+
### **Device Requirements:**
107+
- **Android**: 5.0+ (API level 21+)
108+
- **iOS**: 11.3+
109+
- **Desktop**: Windows 10+, macOS 10.13+, Linux
110+
111+
## 🎯 Pro Tips
112+
113+
1. **Bookmark the app** for easy access before installing
114+
2. **Enable notifications** for better user experience
115+
3. **Use on same network** for best P2P performance
116+
4. **Keep browser updated** for latest PWA features
117+
5. **Check permissions** - allow microphone access for voice chat
118+
119+
## 🆘 Need Help?
120+
121+
If you're having trouble installing or using the PWA:
122+
123+
1. **Check browser compatibility** above
124+
2. **Try a different browser** (Chrome recommended)
125+
3. **Clear browser cache** and try again
126+
4. **Check device storage** - ensure you have enough space
127+
5. **Restart your device** and try again
128+
129+
---
130+
131+
**Enjoy your new PWA experience with PeerChat! 🎉**

README.md

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
1-
# Local P2P Voice Chat (React + Vite + WebRTC)
1+
# PeerChat - P2P Voice Chat (React + Vite + WebRTC + PWA)
22

3-
A zero-backend, end-to-end encrypted voice chat for people on the same Wi‑Fi (or over the internet) using WebRTC and PeerJS. Hosted on GitHub Pages.
3+
A zero-backend, end-to-end encrypted voice chat for people on the same Wi‑Fi (or over the internet) using WebRTC and PeerJS. Now with PWA support for installable, offline-capable experience!
44

55
- Frontend: React + Vite
66
- Signaling: PeerJS public cloud broker (0.peerjs.com)
77
- Media: WebRTC (DTLS-SRTP, E2E encrypted)
8+
- PWA: Installable, offline support, auto-updates
89
- Hosting: GitHub Pages (static)
910

10-
## Quick start (local)
11+
## 🚀 Quick start (local)
1112

1213
1. Install Node.js 18+.
1314
2. Install dependencies and run the dev server:
@@ -19,6 +20,16 @@ npm run dev
1920

2021
Open the printed URL (e.g., http://localhost:5173). Note: getUserMedia (microphone) requires a secure context. It works on localhost but not over plain HTTP LAN IPs. For cross-device testing, deploy to GitHub Pages (HTTPS) or run Vite with HTTPS locally.
2122

23+
## 📱 PWA Installation
24+
25+
PeerChat is now a Progressive Web App! Install it on your device for a native app experience:
26+
27+
- **Android**: Chrome/Edge → Menu → "Add to Home screen"
28+
- **iOS**: Safari → Share → "Add to Home Screen"
29+
- **Desktop**: Chrome/Edge → Install icon in address bar
30+
31+
See [PWA_INSTALLATION.md](./PWA_INSTALLATION.md) for detailed installation steps.
32+
2233
## How to use
2334

2435
1. Each user opens the app; it shows their Peer ID.

generate-icons.html

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>Icon Generator for PeerChat PWA</title>
7+
<style>
8+
body {
9+
font-family: Arial, sans-serif;
10+
max-width: 800px;
11+
margin: 0 auto;
12+
padding: 20px;
13+
background: #f5f5f5;
14+
}
15+
.icon-preview {
16+
display: inline-block;
17+
margin: 10px;
18+
text-align: center;
19+
}
20+
canvas {
21+
border: 1px solid #ddd;
22+
border-radius: 8px;
23+
}
24+
.instructions {
25+
background: white;
26+
padding: 20px;
27+
border-radius: 8px;
28+
margin-bottom: 20px;
29+
}
30+
button {
31+
background: #3b82f6;
32+
color: white;
33+
border: none;
34+
padding: 10px 20px;
35+
border-radius: 5px;
36+
cursor: pointer;
37+
margin: 5px;
38+
}
39+
button:hover {
40+
background: #2563eb;
41+
}
42+
</style>
43+
</head>
44+
<body>
45+
<div class="instructions">
46+
<h1>🎨 PeerChat PWA Icon Generator</h1>
47+
<p>This tool generates placeholder icons for your PWA. Click the buttons below to generate and download the required icon files.</p>
48+
<p><strong>Note:</strong> These are placeholder icons. For production, replace with professional icons designed by a graphic designer.</p>
49+
</div>
50+
51+
<div id="icons"></div>
52+
53+
<script>
54+
function createIcon(size, filename) {
55+
const canvas = document.createElement('canvas');
56+
canvas.width = size;
57+
canvas.height = size;
58+
const ctx = canvas.getContext('2d');
59+
60+
// Background
61+
ctx.fillStyle = '#0f172a';
62+
ctx.fillRect(0, 0, size, size);
63+
64+
// Icon (simple microphone)
65+
ctx.fillStyle = '#3b82f6';
66+
const centerX = size / 2;
67+
const centerY = size / 2;
68+
const iconSize = size * 0.6;
69+
70+
// Microphone body
71+
ctx.beginPath();
72+
ctx.arc(centerX, centerY - iconSize * 0.1, iconSize * 0.2, 0, Math.PI * 2);
73+
ctx.fill();
74+
75+
// Microphone stand
76+
ctx.fillRect(centerX - iconSize * 0.05, centerY - iconSize * 0.1, iconSize * 0.1, iconSize * 0.4);
77+
78+
// Base
79+
ctx.fillRect(centerX - iconSize * 0.15, centerY + iconSize * 0.25, iconSize * 0.3, iconSize * 0.1);
80+
81+
// Sound waves
82+
ctx.strokeStyle = '#10b981';
83+
ctx.lineWidth = size * 0.02;
84+
for (let i = 0; i < 3; i++) {
85+
ctx.beginPath();
86+
ctx.arc(centerX, centerY, iconSize * 0.3 + i * iconSize * 0.1, 0, Math.PI);
87+
ctx.stroke();
88+
}
89+
90+
return canvas;
91+
}
92+
93+
function downloadCanvas(canvas, filename) {
94+
const link = document.createElement('a');
95+
link.download = filename;
96+
link.href = canvas.toDataURL();
97+
link.click();
98+
}
99+
100+
const iconSizes = [
101+
{ size: 16, name: 'favicon-16x16.png' },
102+
{ size: 32, name: 'favicon-32x32.png' },
103+
{ size: 180, name: 'apple-touch-icon.png' },
104+
{ size: 192, name: 'pwa-192x192.png' },
105+
{ size: 512, name: 'pwa-512x512.png' },
106+
{ size: 150, name: 'mstile-150x150.png' }
107+
];
108+
109+
iconSizes.forEach(icon => {
110+
const container = document.createElement('div');
111+
container.className = 'icon-preview';
112+
113+
const canvas = createIcon(icon.size, icon.name);
114+
container.appendChild(canvas);
115+
116+
const button = document.createElement('button');
117+
button.textContent = `Download ${icon.name}`;
118+
button.onclick = () => downloadCanvas(canvas, icon.name);
119+
container.appendChild(button);
120+
121+
const label = document.createElement('div');
122+
label.textContent = `${icon.size}x${icon.size}px`;
123+
container.appendChild(label);
124+
125+
document.getElementById('icons').appendChild(container);
126+
});
127+
128+
// Generate favicon.ico (16x16)
129+
const faviconCanvas = createIcon(16, 'favicon.ico');
130+
const faviconButton = document.createElement('button');
131+
faviconButton.textContent = 'Download favicon.ico';
132+
faviconButton.onclick = () => downloadCanvas(faviconCanvas, 'favicon.ico');
133+
faviconButton.style.marginTop = '20px';
134+
document.body.appendChild(faviconButton);
135+
</script>
136+
</body>
137+
</html>

index.html

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,24 @@
44
<meta charset="UTF-8" />
55
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
66
<meta name="description" content="Local Wi‑Fi P2P voice chat using WebRTC (PeerJS)" />
7-
<title>Local P2P Voice Chat</title>
7+
<meta name="theme-color" content="#0f172a" />
8+
<meta name="apple-mobile-web-app-capable" content="yes" />
9+
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
10+
<meta name="apple-mobile-web-app-title" content="PeerChat" />
11+
<meta name="msapplication-TileColor" content="#0f172a" />
12+
<meta name="msapplication-config" content="/browserconfig.xml" />
13+
14+
<!-- Icons -->
15+
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
16+
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
17+
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
18+
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
19+
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#0f172a" />
20+
21+
<!-- Manifest -->
22+
<link rel="manifest" href="/manifest.json" />
23+
24+
<title>PeerChat - P2P Voice Chat</title>
825
</head>
926
<body>
1027
<div id="root"></div>

package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,13 @@
1111
"dependencies": {
1212
"peerjs": "1.5.2",
1313
"react": "18.3.1",
14-
"react-dom": "18.3.1"
14+
"react-dom": "18.3.1",
15+
"workbox-window": "^7.0.0"
1516
},
1617
"devDependencies": {
1718
"@vitejs/plugin-react": "4.3.3",
18-
"vite": "5.4.9"
19+
"vite": "5.4.9",
20+
"vite-plugin-pwa": "^0.17.4"
1921
},
2022
"repository": {
2123
"type": "git",

public/apple-touch-icon.png

6.52 KB
Loading

public/browserconfig.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<browserconfig>
3+
<msapplication>
4+
<tile>
5+
<square150x150logo src="/mstile-150x150.png"/>
6+
<TileColor>#0f172a</TileColor>
7+
</tile>
8+
</msapplication>
9+
</browserconfig>

public/favicon-16x16.png

339 Bytes
Loading

public/favicon-32x32.png

779 Bytes
Loading

public/favicon.ico

339 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)