Skip to content

Commit cae89fe

Browse files
committed
feat: add PWA support with install prompt and offline handling
- Implemented PWA manifest and icons for PairUX application. - Created a script to generate PNG icons from SVG templates. - Added offline page to inform users of connectivity issues. - Developed service worker for caching and offline support. - Introduced InstallPrompt component to facilitate PWA installation. - Created hooks for managing PWA installation state and user preferences.
1 parent f6f7bfa commit cae89fe

29 files changed

Lines changed: 841 additions & 53 deletions

.claude/settings.local.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,9 @@
159159
"Bash(pnpm --filter web build:*)",
160160
"Bash(pnpm --filter web test -- --run src/app/join/[joinCode]/page.test.tsx src/app/session/[id]/page.test.tsx)",
161161
"Bash(pnpm --filter web test)",
162-
"Bash(pnpm --filter web lint:*)"
162+
"Bash(pnpm --filter web lint:*)",
163+
"Bash(xargs -I {} bash -c 'echo \"\"=== {} ===\"\" && wc -l {}')",
164+
"Bash(node scripts/generate-pwa-icons.mjs:*)"
163165
],
164166
"deny": ["Bash(npm *)", "Bash(npx *)"],
165167
"additionalDirectories": [

TODO.md

Lines changed: 48 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -71,17 +71,17 @@
7171
- [x] Fullscreen toggle
7272
- [x] Connection status indicator
7373

74-
- [ ] **Remote Control (Viewer)**
75-
- [ ] Request control button
76-
- [ ] Control status indicator (view-only/granted)
77-
- [ ] Mouse input capture & transmission
78-
- [ ] Keyboard input capture & transmission
79-
- [ ] Multi-cursor overlay (see other participants)
80-
81-
- [ ] **PWA Features**
82-
- [ ] Service worker for offline shell
83-
- [ ] Web app manifest
84-
- [ ] Install prompt
74+
- [x] **Remote Control (Viewer)**
75+
- [x] Request control button
76+
- [x] Control status indicator (view-only/granted)
77+
- [x] Mouse input capture & transmission
78+
- [x] Keyboard input capture & transmission
79+
- [x] Multi-cursor overlay (see other participants)
80+
81+
- [x] **PWA Features**
82+
- [x] Service worker for offline shell
83+
- [x] Web app manifest
84+
- [x] Install prompt
8585
- [ ] Push notification support (future)
8686

8787
---
@@ -90,53 +90,53 @@
9090

9191
### API Endpoints (Server-Side)
9292

93-
- [ ] **POST /api/chat/send**
94-
- [ ] Validate session membership
95-
- [ ] Store message in Supabase
96-
- [ ] Broadcast via Supabase Realtime
97-
- [ ] Rate limiting (10 msg/min)
93+
- [x] **POST /api/chat/send**
94+
- [x] Validate session membership
95+
- [x] Store message in Supabase
96+
- [x] Broadcast via Supabase Realtime
97+
- [x] Rate limiting (10 msg/min)
9898

99-
- [ ] **GET /api/chat/stream (SSE)**
100-
- [ ] Server-Sent Events connection
101-
- [ ] Real-time message delivery
102-
- [ ] Heartbeat/keepalive
103-
- [ ] Reconnection handling
99+
- [x] **GET /api/chat/stream (SSE)**
100+
- [x] Server-Sent Events connection
101+
- [x] Real-time message delivery
102+
- [x] Heartbeat/keepalive
103+
- [x] Reconnection handling
104104

105-
- [ ] **GET /api/chat/history**
106-
- [ ] Fetch last 100 messages
107-
- [ ] Pagination support
108-
- [ ] Session-scoped access
105+
- [x] **GET /api/chat/history**
106+
- [x] Fetch last 100 messages
107+
- [x] Pagination support
108+
- [x] Session-scoped access
109109

110110
### Chat UI Components
111111

112-
- [ ] **Chat Panel**
113-
- [ ] Collapsible sidebar/drawer
114-
- [ ] Message list with auto-scroll
115-
- [ ] Participant avatars/colors
116-
- [ ] Timestamp display
117-
- [ ] Unread message indicator
118-
119-
- [ ] **Message Input**
120-
- [ ] Text input with send button
121-
- [ ] Enter to send, Shift+Enter for newline
122-
- [ ] Character limit (500)
112+
- [x] **Chat Panel**
113+
- [x] Collapsible sidebar/drawer
114+
- [x] Message list with auto-scroll
115+
- [x] Participant avatars/colors
116+
- [x] Timestamp display
117+
- [x] Unread message indicator
118+
119+
- [x] **Message Input**
120+
- [x] Text input with send button
121+
- [x] Enter to send, Shift+Enter for newline
122+
- [x] Character limit (500)
123123
- [ ] Typing indicator (optional)
124124

125-
- [ ] **Message Types**
126-
- [ ] Text messages
127-
- [ ] System messages (join/leave/control)
128-
- [ ] Emoji support (native)
125+
- [x] **Message Types**
126+
- [x] Text messages
127+
- [x] System messages (join/leave/control)
128+
- [x] Emoji support (native)
129129

130130
### Data Model
131131

132-
- [ ] **chat_messages table**
133-
- [ ] id (uuid)
134-
- [ ] session_id (fk)
135-
- [ ] user_id (fk, nullable for guests)
136-
- [ ] display_name (string)
137-
- [ ] content (text)
138-
- [ ] message_type (text/system)
139-
- [ ] created_at (timestamp)
132+
- [x] **chat_messages table**
133+
- [x] id (uuid)
134+
- [x] session_id (fk)
135+
- [x] user_id (fk, nullable for guests)
136+
- [x] display_name (string)
137+
- [x] content (text)
138+
- [x] message_type (text/system)
139+
- [x] created_at (timestamp)
140140

141141
---
142142

apps/web/next.config.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11
import type { NextConfig } from 'next';
2+
import withSerwistInit from '@serwist/next';
3+
4+
const withSerwist = withSerwistInit({
5+
swSrc: 'src/app/sw.ts',
6+
swDest: 'public/sw.js',
7+
disable: process.env.NODE_ENV === 'development',
8+
});
29

310
const nextConfig: NextConfig = {
411
// Enable React strict mode for better development experience
@@ -55,4 +62,4 @@ const nextConfig: NextConfig = {
5562
},
5663
};
5764

58-
export default nextConfig;
65+
export default withSerwist(nextConfig);

apps/web/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
"clean": "rm -rf .next out node_modules"
1717
},
1818
"dependencies": {
19+
"@serwist/next": "^9.5.0",
1920
"@supabase/ssr": "^0.5.0",
2021
"@supabase/supabase-js": "^2.47.0",
2122
"clsx": "^2.1.0",
@@ -26,6 +27,7 @@
2627
"react": "^19.0.0",
2728
"react-dom": "^19.0.0",
2829
"react-type-animation": "^3.2.0",
30+
"serwist": "^9.5.0",
2931
"tailwind-merge": "^2.6.0",
3032
"zod": "^3.24.0"
3133
},
@@ -42,6 +44,7 @@
4244
"autoprefixer": "^10.4.20",
4345
"jsdom": "^25.0.0",
4446
"postcss": "^8.4.49",
47+
"sharp": "^0.34.5",
4548
"tailwindcss": "^4.0.0",
4649
"typescript": "^5.7.0",
4750
"vitest": "^2.1.0"
7.05 KB
Loading

apps/web/public/favicon-16x16.png

515 Bytes
Loading

apps/web/public/favicon-32x32.png

1.35 KB
Loading

apps/web/public/favicon.ico

1.35 KB
Binary file not shown.

apps/web/public/favicon.svg

Lines changed: 15 additions & 0 deletions
Loading
Lines changed: 15 additions & 0 deletions
Loading

0 commit comments

Comments
 (0)