solid-chat 0.0.1 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +121 -30
- package/bin/cli.js +77 -0
- package/icons/icon-128.png +0 -0
- package/icons/icon-144.png +0 -0
- package/icons/icon-152.png +0 -0
- package/icons/icon-192.png +0 -0
- package/icons/icon-384.png +0 -0
- package/icons/icon-512.png +0 -0
- package/icons/icon-72.png +0 -0
- package/icons/icon-96.png +0 -0
- package/icons/icon.svg +22 -0
- package/index.html +1065 -0
- package/manifest.json +57 -0
- package/package.json +20 -4
- package/src/chatListPane.js +233 -41
- package/src/index.test.js +71 -0
- package/src/longChatPane.js +870 -28
package/README.md
CHANGED
|
@@ -2,59 +2,137 @@
|
|
|
2
2
|
|
|
3
3
|
Modern, decentralized chat app built on the [Solid](https://solidproject.org) protocol.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
**Live App:** [solid-chat.com/app](https://solid-chat.com/app)
|
|
6
6
|
|
|
7
7
|
## Features
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
-
|
|
9
|
+
### Core
|
|
10
|
+
- Clean, WhatsApp-style messenger UI
|
|
11
|
+
- Decentralized - messages stored in Solid pods
|
|
11
12
|
- Implements the [Solid Chat specification](https://solid.github.io/chat/)
|
|
12
|
-
- Works with any Solid pod provider
|
|
13
|
-
- Clickable WebID links on author names
|
|
13
|
+
- Works with any Solid pod provider (solidweb.org, solidcommunity.net, inrupt.net, etc.)
|
|
14
14
|
- No React/heavy frameworks - vanilla JS
|
|
15
15
|
|
|
16
|
+
### Authentication
|
|
17
|
+
- Solid OIDC authentication
|
|
18
|
+
- Multi-provider support (enter any IDP)
|
|
19
|
+
- Persistent sessions
|
|
20
|
+
|
|
21
|
+
### Real-time
|
|
22
|
+
- WebSocket updates (NSS `Updates-Via` header)
|
|
23
|
+
- WebSocketChannel2023 support (CSS/solidcommunity.net)
|
|
24
|
+
- Notification sounds when tab is hidden (toggleable)
|
|
25
|
+
|
|
26
|
+
### Messaging
|
|
27
|
+
- Send and receive messages
|
|
28
|
+
- Edit your own messages (requires Write permission)
|
|
29
|
+
- Delete your own messages (requires Write permission)
|
|
30
|
+
- Simple markdown: `*bold*`, `_italic_`, `~strike~`, `` `code` ``, ` ```code blocks``` `
|
|
31
|
+
- Emoji picker
|
|
32
|
+
- Emoji reactions: 👍 ❤️ 😂 😮 😢 🎉
|
|
33
|
+
|
|
34
|
+
### Media
|
|
35
|
+
- File upload to your pod (📎 button)
|
|
36
|
+
- Paste images directly (Ctrl+V)
|
|
37
|
+
- Auto-expand images, video, and audio inline
|
|
38
|
+
- Clickable URLs
|
|
39
|
+
|
|
40
|
+
### Sidebar
|
|
41
|
+
- Chat list with recent chats
|
|
42
|
+
- Type Index auto-discovery of your chats
|
|
43
|
+
- Create new chats on your pod
|
|
44
|
+
- Manual chat URL addition
|
|
45
|
+
- Persistent storage (localStorage)
|
|
46
|
+
|
|
47
|
+
### Sharing & Deep Links
|
|
48
|
+
- Share button (📋) copies shareable link
|
|
49
|
+
- Deep link support: `?chat=<url>` loads or creates chat
|
|
50
|
+
- Auto-create: links to your pod create rooms on demand
|
|
51
|
+
- Type Index registration for discoverability
|
|
52
|
+
|
|
53
|
+
### UI/UX
|
|
54
|
+
- Avatar display from WebID profiles
|
|
55
|
+
- Clickable author names (links to WebID)
|
|
56
|
+
- Clickable timestamps (permalinks to message URI)
|
|
57
|
+
- "(edited)" indicator for edited messages
|
|
58
|
+
- Message count in header
|
|
59
|
+
|
|
16
60
|
## Quick Start
|
|
17
61
|
|
|
18
62
|
```bash
|
|
19
|
-
#
|
|
63
|
+
# Run instantly (no clone needed)
|
|
64
|
+
npx solid-chat
|
|
65
|
+
|
|
66
|
+
# Or clone and run
|
|
20
67
|
git clone https://github.com/solid-chat/app.git
|
|
21
68
|
cd app
|
|
69
|
+
npm install
|
|
70
|
+
npm start
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Usage
|
|
74
|
+
|
|
75
|
+
1. Enter your Solid IDP (e.g., `solidweb.org`) and click Login
|
|
76
|
+
2. Select a chat from the sidebar or add a new one
|
|
77
|
+
3. Start chatting!
|
|
22
78
|
|
|
23
|
-
|
|
24
|
-
|
|
79
|
+
### Default Global Chats
|
|
80
|
+
- `https://solid-chat.solidweb.org/public/global/chat.ttl` (faster)
|
|
81
|
+
- `https://solid-chat.solidcommunity.net/public/global/chat.ttl`
|
|
25
82
|
|
|
26
|
-
|
|
27
|
-
|
|
83
|
+
### Deep Links
|
|
84
|
+
|
|
85
|
+
Share chats with a URL:
|
|
86
|
+
```
|
|
87
|
+
https://solid-chat.com/app?chat=https://you.solidweb.org/public/chats/my-room.ttl
|
|
28
88
|
```
|
|
29
89
|
|
|
30
|
-
|
|
90
|
+
**Behavior:**
|
|
91
|
+
- If chat exists → loads it
|
|
92
|
+
- If chat doesn't exist AND it's your pod → creates it automatically
|
|
93
|
+
- Change one character → instant new room
|
|
31
94
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
95
|
+
**Create rooms on demand:**
|
|
96
|
+
```
|
|
97
|
+
https://solid-chat.com/app?chat=https://you.pod/public/chats/meeting-monday.ttl
|
|
98
|
+
https://solid-chat.com/app?chat=https://you.pod/public/chats/meeting-tuesday.ttl
|
|
99
|
+
```
|
|
35
100
|
|
|
36
|
-
|
|
37
|
-
- `https://solidos.solidcommunity.net/Team/SolidOs%20team%20chat/2022/02/09/chat.ttl`
|
|
101
|
+
Click the share button (📋) in any chat to copy the shareable link.
|
|
38
102
|
|
|
39
103
|
## Chat Data Format
|
|
40
104
|
|
|
41
|
-
|
|
105
|
+
Messages use standard Solid chat vocabularies (RDF/Turtle):
|
|
42
106
|
|
|
43
107
|
```turtle
|
|
44
|
-
@prefix flow: <http://www.w3.org/2005/01/wf/flow#>.
|
|
45
108
|
@prefix sioc: <http://rdfs.org/sioc/ns#>.
|
|
46
109
|
@prefix dct: <http://purl.org/dc/terms/>.
|
|
47
110
|
@prefix foaf: <http://xmlns.com/foaf/0.1/>.
|
|
48
111
|
|
|
49
|
-
<#
|
|
50
|
-
a <http://www.w3.org/
|
|
51
|
-
flow:message :msg1 .
|
|
52
|
-
|
|
53
|
-
:msg1
|
|
54
|
-
a flow:Message ;
|
|
112
|
+
<#msg-1234567890>
|
|
113
|
+
a <http://www.w3.org/2005/01/wf/flow#Message> ;
|
|
55
114
|
sioc:content "Hello world!" ;
|
|
56
115
|
dct:created "2024-12-30T10:00:00Z"^^xsd:dateTime ;
|
|
57
|
-
foaf:maker <https://
|
|
116
|
+
foaf:maker <https://you.solidweb.org/profile/card#me> .
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Reactions use Schema.org:
|
|
120
|
+
|
|
121
|
+
```turtle
|
|
122
|
+
@prefix schema: <http://schema.org/>.
|
|
123
|
+
|
|
124
|
+
<#reaction-1234567890>
|
|
125
|
+
a schema:ReactAction ;
|
|
126
|
+
schema:about <#msg-123> ;
|
|
127
|
+
schema:agent <https://you.solidweb.org/profile/card#me> ;
|
|
128
|
+
schema:name "👍" .
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Testing
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
npm install
|
|
135
|
+
npm test
|
|
58
136
|
```
|
|
59
137
|
|
|
60
138
|
## Specification
|
|
@@ -63,11 +141,24 @@ This app implements the [Solid Chat specification](https://solid.github.io/chat/
|
|
|
63
141
|
|
|
64
142
|
## Roadmap
|
|
65
143
|
|
|
66
|
-
- [
|
|
67
|
-
- [
|
|
68
|
-
- [
|
|
69
|
-
- [
|
|
70
|
-
- [
|
|
144
|
+
- [x] Solid OIDC authentication
|
|
145
|
+
- [x] Chat list sidebar
|
|
146
|
+
- [x] Real-time updates (WebSocket + WebSocketChannel2023)
|
|
147
|
+
- [x] Notification sounds
|
|
148
|
+
- [x] File upload
|
|
149
|
+
- [x] Image paste
|
|
150
|
+
- [x] Media auto-expand
|
|
151
|
+
- [x] Simple markdown
|
|
152
|
+
- [x] Edit/delete messages
|
|
153
|
+
- [x] Emoji reactions
|
|
154
|
+
- [x] Create new chats
|
|
155
|
+
- [x] Deep link sharing (`?chat=<url>`)
|
|
156
|
+
- [x] Type Index registration
|
|
157
|
+
- [ ] @mentions with notifications
|
|
158
|
+
- [ ] End-to-end encryption
|
|
159
|
+
- [ ] Mobile responsive sidebar
|
|
160
|
+
- [ ] Unread message badges
|
|
161
|
+
- [ ] Message search
|
|
71
162
|
|
|
72
163
|
## License
|
|
73
164
|
|
package/bin/cli.js
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { createServer } from 'http'
|
|
4
|
+
import { readFileSync, existsSync, statSync } from 'fs'
|
|
5
|
+
import { join, extname } from 'path'
|
|
6
|
+
import { fileURLToPath } from 'url'
|
|
7
|
+
import { dirname } from 'path'
|
|
8
|
+
import open from 'open'
|
|
9
|
+
|
|
10
|
+
const __filename = fileURLToPath(import.meta.url)
|
|
11
|
+
const __dirname = dirname(__filename)
|
|
12
|
+
const ROOT = join(__dirname, '..')
|
|
13
|
+
|
|
14
|
+
const MIME_TYPES = {
|
|
15
|
+
'.html': 'text/html',
|
|
16
|
+
'.js': 'text/javascript',
|
|
17
|
+
'.mjs': 'text/javascript',
|
|
18
|
+
'.css': 'text/css',
|
|
19
|
+
'.json': 'application/json',
|
|
20
|
+
'.png': 'image/png',
|
|
21
|
+
'.jpg': 'image/jpeg',
|
|
22
|
+
'.svg': 'image/svg+xml',
|
|
23
|
+
'.ico': 'image/x-icon',
|
|
24
|
+
'.woff': 'font/woff',
|
|
25
|
+
'.woff2': 'font/woff2',
|
|
26
|
+
'.ttf': 'font/ttf'
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const port = parseInt(process.argv[2]) || 3000
|
|
30
|
+
|
|
31
|
+
const server = createServer((req, res) => {
|
|
32
|
+
let filePath = join(ROOT, req.url === '/' ? 'index.html' : req.url)
|
|
33
|
+
|
|
34
|
+
// Security: prevent directory traversal
|
|
35
|
+
if (!filePath.startsWith(ROOT)) {
|
|
36
|
+
res.writeHead(403)
|
|
37
|
+
res.end('Forbidden')
|
|
38
|
+
return
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Handle directory requests
|
|
42
|
+
if (existsSync(filePath) && statSync(filePath).isDirectory()) {
|
|
43
|
+
filePath = join(filePath, 'index.html')
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const ext = extname(filePath).toLowerCase()
|
|
47
|
+
const contentType = MIME_TYPES[ext] || 'application/octet-stream'
|
|
48
|
+
|
|
49
|
+
try {
|
|
50
|
+
const content = readFileSync(filePath)
|
|
51
|
+
res.writeHead(200, { 'Content-Type': contentType })
|
|
52
|
+
res.end(content)
|
|
53
|
+
} catch (err) {
|
|
54
|
+
if (err.code === 'ENOENT') {
|
|
55
|
+
res.writeHead(404)
|
|
56
|
+
res.end('Not Found')
|
|
57
|
+
} else {
|
|
58
|
+
res.writeHead(500)
|
|
59
|
+
res.end('Server Error')
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
server.listen(port, () => {
|
|
65
|
+
const url = `http://localhost:${port}`
|
|
66
|
+
console.log(`
|
|
67
|
+
╭─────────────────────────────────────╮
|
|
68
|
+
│ │
|
|
69
|
+
│ Solid Chat running at: │
|
|
70
|
+
│ ${url.padEnd(30)}│
|
|
71
|
+
│ │
|
|
72
|
+
│ Press Ctrl+C to stop │
|
|
73
|
+
│ │
|
|
74
|
+
╰─────────────────────────────────────╯
|
|
75
|
+
`)
|
|
76
|
+
open(url)
|
|
77
|
+
})
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/icons/icon.svg
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<svg width="512" height="512" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<defs>
|
|
3
|
+
<linearGradient id="bg" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
4
|
+
<stop offset="0%" style="stop-color:#667eea"/>
|
|
5
|
+
<stop offset="100%" style="stop-color:#9f7aea"/>
|
|
6
|
+
</linearGradient>
|
|
7
|
+
</defs>
|
|
8
|
+
|
|
9
|
+
<!-- Background -->
|
|
10
|
+
<rect width="512" height="512" rx="96" fill="url(#bg)"/>
|
|
11
|
+
|
|
12
|
+
<!-- Chat bubble -->
|
|
13
|
+
<g transform="translate(96, 116)">
|
|
14
|
+
<rect x="0" y="0" width="320" height="220" rx="40" fill="rgba(255,255,255,0.95)"/>
|
|
15
|
+
<polygon points="40,220 40,280 100,220" fill="rgba(255,255,255,0.95)"/>
|
|
16
|
+
|
|
17
|
+
<!-- Three dots -->
|
|
18
|
+
<circle cx="100" cy="110" r="24" fill="#667eea"/>
|
|
19
|
+
<circle cx="160" cy="110" r="24" fill="#7c8fef"/>
|
|
20
|
+
<circle cx="220" cy="110" r="24" fill="#9f7aea"/>
|
|
21
|
+
</g>
|
|
22
|
+
</svg>
|