agentchannel 0.5.2 → 0.5.3
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/dist/web.js +176 -102
- package/dist/web.js.map +1 -1
- package/package.json +1 -1
package/dist/web.js
CHANGED
|
@@ -2,75 +2,133 @@ import { createServer } from "node:http";
|
|
|
2
2
|
import mqtt from "mqtt";
|
|
3
3
|
import { deriveKey, hashRoom, decrypt } from "./crypto.js";
|
|
4
4
|
const MAX_HISTORY = 200;
|
|
5
|
-
const CSS = `*,*::before,*::after{margin:0;padding:0;box-sizing:border-box}
|
|
6
|
-
:root{--bg-primary:#ffffff;--bg-secondary:#f8f9fa;--bg-sidebar:#1a1a2e;--bg-hover:rgba(0,0,0,0.04);--text-primary:#1a1a2e;--text-secondary:#6b7280;--text-muted:#9ca3af;--text-sidebar:#a0aec0;--text-sidebar-active:#ffffff;--mention-bg:rgba(59,130,246,0.1);--mention-text:#2563eb;--mention-border:rgba(59,130,246,0.2);--system-text:#9ca3af;--channel-bg:rgba(16,185,129,0.1);--channel-text:#059669;--channel-border:rgba(16,185,129,0.2);--divider:rgba(0,0,0,0.08);--sidebar-hover:rgba(255,255,255,0.08);--sidebar-active:rgba(255,255,255,0.15);--font-sans:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;--radius-sm:4px;--radius-lg:12px}
|
|
7
|
-
@media(prefers-color-scheme:dark){:root{--bg-primary:#1e1e2e;--bg-secondary:#181825;--bg-sidebar:#11111b;--bg-hover:rgba(255,255,255,0.05);--text-primary:#cdd6f4;--text-secondary:#a6adc8;--text-muted:#585b70;--mention-bg:rgba(137,180,250,0.15);--mention-text:#89b4fa;--mention-border:rgba(137,180,250,0.25);--system-text:#585b70;--channel-bg:rgba(166,227,161,0.1);--channel-text:#a6e3a1;--channel-border:rgba(166,227,161,0.2);--divider:rgba(255,255,255,0.06);--sidebar-hover:rgba(255,255,255,0.06);--sidebar-active:rgba(255,255,255,0.12)}}
|
|
8
|
-
html{font-size:15px;-webkit-font-smoothing:antialiased}
|
|
9
|
-
body{font-family:var(--font-sans);background:var(--bg-primary);color:var(--text-primary);line-height:1.6;height:100vh;overflow:hidden}
|
|
10
|
-
.app{display:flex;height:100vh}
|
|
11
|
-
.sidebar{width:220px;background:var(--bg-sidebar);display:flex;flex-direction:column;flex-shrink:0}
|
|
12
|
-
.sidebar__header{padding:16px;font-size:1rem;font-weight:700;color:#e94560;border-bottom:1px solid rgba(255,255,255,0.06)}
|
|
13
|
-
.sidebar__channels{flex:1;padding:8px;overflow-y:auto}
|
|
14
|
-
.sidebar__channel{display:flex;align-items:center;gap:8px;padding:6px 12px;border-radius:6px;cursor:pointer;color:var(--text-sidebar);font-size:0.9rem;transition:background 0.1s}
|
|
15
|
-
.sidebar__channel:hover{background:var(--sidebar-hover)}
|
|
16
|
-
.sidebar__channel.active{background:var(--sidebar-active);color:var(--text-sidebar-active);font-weight:600}
|
|
17
|
-
.sidebar__channel .hash{color:#6b7280;font-weight:400}
|
|
18
|
-
.sidebar__channel .unread{background:#e94560;color:#fff;font-size:0.65rem;padding:1px 6px;border-radius:9999px;margin-left:auto}
|
|
19
|
-
.sidebar__status{padding:12px 16px;font-size:0.75rem;color:var(--text-sidebar);border-top:1px solid rgba(255,255,255,0.06)}
|
|
20
|
-
.sidebar__status.connected{color:#4ade80}
|
|
21
|
-
.main{flex:1;display:flex;flex-direction:column;min-width:0}
|
|
22
|
-
.main__header{padding:14px 20px;border-bottom:1px solid var(--divider);font-weight:600;font-size:0.95rem;background:var(--bg-secondary)}
|
|
23
|
-
.message-list{flex:1;overflow-y:auto;padding:8px 0}
|
|
24
|
-
.message{display:flex;padding:2px 20px;transition:background-color 0.1s ease}
|
|
25
|
-
.message:hover{background:var(--bg-hover)}
|
|
26
|
-
.message__gutter{width:40px;flex-shrink:0;margin-right:12px;display:flex;align-items:flex-start;justify-content:center;padding-top:4px}
|
|
27
|
-
.message__avatar{width:36px;height:36px;border-radius:var(--radius-lg);background:var(--avatar-color,#7c6bf0);color:#fff;font-weight:700;font-size:0.85rem;display:flex;align-items:center;justify-content:center;user-select:none}
|
|
28
|
-
.message__body{flex:1;min-width:0}
|
|
29
|
-
.message--first{padding-top:10px;margin-top:4px}
|
|
30
|
-
.message--first+.message--first{border-top:1px solid var(--divider)}
|
|
31
|
-
.message--system+.message--first,.message--first:first-child{border-top:none}
|
|
32
|
-
.message__header{display:flex;align-items:baseline;gap:8px;margin-bottom:2px;flex-wrap:wrap}
|
|
33
|
-
.message__sender{font-weight:700;font-size:0.935rem;color:var(--sender-color,#7c6bf0)}
|
|
34
|
-
.message__channel{display:inline-block;font-size:0.72rem;font-weight:600;padding:1px 7px;border-radius:9999px;background:var(--channel-bg);color:var(--channel-text);border:1px solid var(--channel-border);white-space:nowrap}
|
|
35
|
-
.message__time{font-size:0.72rem;color:var(--text-muted);font-variant-numeric:tabular-nums;white-space:nowrap}
|
|
36
|
-
.message__time--hover{opacity:0;font-size:0.68rem;transition:opacity 0.15s ease;padding-top:4px}
|
|
37
|
-
.message--grouped:hover .message__time--hover{opacity:1}
|
|
38
|
-
.message__content{font-size:0.935rem;line-height:1.65;word-wrap:break-word}
|
|
39
|
-
.message--grouped{padding-top:1px;padding-bottom:1px}
|
|
40
|
-
.mention{display:inline;background:var(--mention-bg);color:var(--mention-text);padding:1px 5px;border-radius:var(--radius-sm);font-weight:600;font-size:0.9rem;border:1px solid var(--mention-border);white-space:nowrap}
|
|
41
|
-
.message--system{padding-top:6px;padding-bottom:6px}
|
|
42
|
-
.message--system .message__body{display:flex;align-items:center;gap:10px;padding-left:52px}
|
|
43
|
-
.message__system-text{font-size:0.82rem;color:var(--system-text);font-style:italic}
|
|
44
|
-
.message--system:hover{background:transparent}
|
|
45
|
-
.empty{display:flex;align-items:center;justify-content:center;height:100%;color:var(--text-muted);font-size:0.9rem}
|
|
46
|
-
::-webkit-scrollbar{width:6px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:rgba(128,128,128,0.2);border-radius:3px}
|
|
47
|
-
@media(max-width:600px){.sidebar{width:60px}.sidebar__header{font-size:0.7rem;padding:12px 8px}.sidebar__channel{padding:6px 8px;font-size:0.75rem}.sidebar__channel .hash{display:none}.sidebar__status{display:none}}`;
|
|
48
5
|
const HTML = `<!DOCTYPE html>
|
|
49
6
|
<html lang="en">
|
|
50
7
|
<head>
|
|
51
8
|
<meta charset="utf-8">
|
|
52
9
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
53
10
|
<title>AgentChannel</title>
|
|
54
|
-
<style
|
|
11
|
+
<style>
|
|
12
|
+
*,*::before,*::after{margin:0;padding:0;box-sizing:border-box}
|
|
13
|
+
|
|
14
|
+
:root {
|
|
15
|
+
--bg: #ffffff;
|
|
16
|
+
--bg-alt: #f7f7f8;
|
|
17
|
+
--bg-sidebar: #f7f7f8;
|
|
18
|
+
--bg-bubble: #f7f7f8;
|
|
19
|
+
--bg-bubble-self: #ececf1;
|
|
20
|
+
--bg-hover: rgba(0,0,0,0.02);
|
|
21
|
+
--text: #0d0d0d;
|
|
22
|
+
--text-secondary: #6b6c7b;
|
|
23
|
+
--text-muted: #acacbe;
|
|
24
|
+
--text-sidebar: #6b6c7b;
|
|
25
|
+
--text-sidebar-active: #0d0d0d;
|
|
26
|
+
--mention-bg: rgba(59,130,246,0.08);
|
|
27
|
+
--mention-text: #2563eb;
|
|
28
|
+
--border: #e5e5e5;
|
|
29
|
+
--accent: #0d0d0d;
|
|
30
|
+
--sidebar-active: #ececf1;
|
|
31
|
+
--font: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
@media (prefers-color-scheme: dark) {
|
|
35
|
+
:root {
|
|
36
|
+
--bg: #212121;
|
|
37
|
+
--bg-alt: #2f2f2f;
|
|
38
|
+
--bg-sidebar: #171717;
|
|
39
|
+
--bg-bubble: #2f2f2f;
|
|
40
|
+
--bg-bubble-self: #303030;
|
|
41
|
+
--bg-hover: rgba(255,255,255,0.02);
|
|
42
|
+
--text: #ececec;
|
|
43
|
+
--text-secondary: #9b9b9b;
|
|
44
|
+
--text-muted: #666;
|
|
45
|
+
--text-sidebar: #9b9b9b;
|
|
46
|
+
--text-sidebar-active: #ececec;
|
|
47
|
+
--mention-bg: rgba(137,180,250,0.12);
|
|
48
|
+
--mention-text: #89b4fa;
|
|
49
|
+
--border: #383838;
|
|
50
|
+
--accent: #ececec;
|
|
51
|
+
--sidebar-active: #2f2f2f;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
html { font-size: 16px; -webkit-font-smoothing: antialiased; }
|
|
56
|
+
body { font-family: var(--font); background: var(--bg); color: var(--text); height: 100vh; overflow: hidden; }
|
|
57
|
+
|
|
58
|
+
.app { display: flex; height: 100vh; }
|
|
59
|
+
|
|
60
|
+
/* Sidebar */
|
|
61
|
+
.sidebar { width: 260px; background: var(--bg-sidebar); border-right: 1px solid var(--border); display: flex; flex-direction: column; flex-shrink: 0; }
|
|
62
|
+
.sidebar__header { padding: 20px; font-size: 0.875rem; font-weight: 600; color: var(--text-secondary); letter-spacing: 0.05em; text-transform: uppercase; }
|
|
63
|
+
.sidebar__channels { flex: 1; padding: 0 8px; overflow-y: auto; }
|
|
64
|
+
.sidebar__channel { display: flex; align-items: center; padding: 10px 12px; border-radius: 8px; cursor: pointer; color: var(--text-sidebar); font-size: 0.9rem; transition: all 0.15s; margin-bottom: 2px; }
|
|
65
|
+
.sidebar__channel:hover { background: var(--bg-hover); }
|
|
66
|
+
.sidebar__channel.active { background: var(--sidebar-active); color: var(--text-sidebar-active); font-weight: 600; }
|
|
67
|
+
.sidebar__channel .icon { width: 20px; margin-right: 10px; font-size: 1.1rem; text-align: center; }
|
|
68
|
+
.sidebar__status { padding: 16px 20px; font-size: 0.75rem; color: var(--text-muted); border-top: 1px solid var(--border); }
|
|
69
|
+
.sidebar__status.connected { color: #22c55e; }
|
|
70
|
+
|
|
71
|
+
/* Main */
|
|
72
|
+
.main { flex: 1; display: flex; flex-direction: column; min-width: 0; }
|
|
73
|
+
.main__header { padding: 16px 24px; border-bottom: 1px solid var(--border); font-weight: 600; font-size: 1rem; display: flex; align-items: center; gap: 8px; }
|
|
74
|
+
.main__header .channel-name { color: var(--text); }
|
|
75
|
+
.main__header .channel-desc { color: var(--text-muted); font-weight: 400; font-size: 0.85rem; }
|
|
76
|
+
|
|
77
|
+
/* Messages */
|
|
78
|
+
.messages { flex: 1; overflow-y: auto; padding: 24px 0; }
|
|
79
|
+
.messages__inner { max-width: 768px; margin: 0 auto; padding: 0 24px; }
|
|
80
|
+
|
|
81
|
+
.conversation { margin-bottom: 24px; }
|
|
82
|
+
.conversation__header { display: flex; align-items: flex-start; gap: 16px; margin-bottom: 4px; }
|
|
83
|
+
.conversation__avatar { width: 36px; height: 36px; border-radius: 50%; background: var(--accent); color: var(--bg); font-weight: 700; font-size: 0.8rem; display: flex; align-items: center; justify-content: center; flex-shrink: 0; margin-top: 2px; }
|
|
84
|
+
.conversation__meta { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
|
|
85
|
+
.conversation__sender { font-weight: 600; font-size: 0.9rem; }
|
|
86
|
+
.conversation__channel { font-size: 0.75rem; color: var(--text-muted); }
|
|
87
|
+
.conversation__time { font-size: 0.75rem; color: var(--text-muted); }
|
|
88
|
+
|
|
89
|
+
.conversation__bubble { margin-left: 52px; padding: 12px 16px; background: var(--bg-bubble); border-radius: 12px; font-size: 0.938rem; line-height: 1.7; color: var(--text); word-wrap: break-word; margin-bottom: 6px; }
|
|
90
|
+
.conversation__bubble--grouped { margin-top: 2px; }
|
|
91
|
+
|
|
92
|
+
.mention { background: var(--mention-bg); color: var(--mention-text); padding: 1px 4px; border-radius: 4px; font-weight: 600; font-size: 0.875rem; }
|
|
93
|
+
|
|
94
|
+
.system-msg { text-align: center; font-size: 0.8rem; color: var(--text-muted); padding: 8px 0; }
|
|
95
|
+
|
|
96
|
+
.empty { display: flex; align-items: center; justify-content: center; height: 100%; color: var(--text-muted); font-size: 0.9rem; }
|
|
97
|
+
|
|
98
|
+
::-webkit-scrollbar { width: 6px; }
|
|
99
|
+
::-webkit-scrollbar-track { background: transparent; }
|
|
100
|
+
::-webkit-scrollbar-thumb { background: rgba(128,128,128,0.15); border-radius: 3px; }
|
|
101
|
+
|
|
102
|
+
@media (max-width: 700px) {
|
|
103
|
+
.sidebar { width: 0; display: none; }
|
|
104
|
+
.messages__inner { padding: 0 16px; }
|
|
105
|
+
.conversation__bubble { margin-left: 0; }
|
|
106
|
+
}
|
|
107
|
+
</style>
|
|
55
108
|
</head>
|
|
56
109
|
<body>
|
|
57
110
|
<div class="app">
|
|
58
111
|
<div class="sidebar">
|
|
59
|
-
<div class="sidebar__header">
|
|
112
|
+
<div class="sidebar__header">Channels</div>
|
|
60
113
|
<div class="sidebar__channels" id="channel-list"></div>
|
|
61
114
|
<div class="sidebar__status" id="status">connecting...</div>
|
|
62
115
|
</div>
|
|
63
116
|
<div class="main">
|
|
64
|
-
<div class="main__header"
|
|
65
|
-
|
|
66
|
-
<
|
|
117
|
+
<div class="main__header">
|
|
118
|
+
<span class="channel-name" id="header-name"># all</span>
|
|
119
|
+
<span class="channel-desc" id="header-desc">All channels</span>
|
|
120
|
+
</div>
|
|
121
|
+
<div class="messages" id="messages-scroll">
|
|
122
|
+
<div class="messages__inner" id="messages">
|
|
123
|
+
<div class="empty">Waiting for messages...</div>
|
|
124
|
+
</div>
|
|
67
125
|
</div>
|
|
68
126
|
</div>
|
|
69
127
|
</div>
|
|
70
128
|
<script src="https://unpkg.com/mqtt/dist/mqtt.min.js"></script>
|
|
71
129
|
<script>
|
|
72
130
|
const CONFIG = __CONFIG__;
|
|
73
|
-
const COLORS = ["#
|
|
131
|
+
const COLORS = ["#6366f1","#ec4899","#14b8a6","#f59e0b","#3b82f6","#ef4444","#8b5cf6","#22c55e"];
|
|
74
132
|
const senderColors = {};
|
|
75
133
|
let activeChannel = "all";
|
|
76
134
|
const allMessages = [];
|
|
@@ -78,18 +136,18 @@ const allMessages = [];
|
|
|
78
136
|
const encoder = new TextEncoder();
|
|
79
137
|
const decoder = new TextDecoder();
|
|
80
138
|
|
|
81
|
-
function
|
|
139
|
+
function getColor(name) {
|
|
82
140
|
if (!senderColors[name]) senderColors[name] = COLORS[Object.keys(senderColors).length % COLORS.length];
|
|
83
141
|
return senderColors[name];
|
|
84
142
|
}
|
|
85
143
|
|
|
86
|
-
async function deriveKey(
|
|
87
|
-
const km = await crypto.subtle.importKey("raw",encoder.encode(
|
|
144
|
+
async function deriveKey(s) {
|
|
145
|
+
const km = await crypto.subtle.importKey("raw",encoder.encode(s),"PBKDF2",false,["deriveKey"]);
|
|
88
146
|
return crypto.subtle.deriveKey({name:"PBKDF2",salt:encoder.encode("agentchannel-v1"),iterations:100000,hash:"SHA-256"},km,{name:"AES-GCM",length:256},false,["encrypt","decrypt"]);
|
|
89
147
|
}
|
|
90
148
|
|
|
91
|
-
async function hashRoom(
|
|
92
|
-
const h = await crypto.subtle.digest("SHA-256",encoder.encode(
|
|
149
|
+
async function hashRoom(c) {
|
|
150
|
+
const h = await crypto.subtle.digest("SHA-256",encoder.encode(c));
|
|
93
151
|
return Array.from(new Uint8Array(h)).map(b=>b.toString(16).padStart(2,"0")).join("").slice(0,16);
|
|
94
152
|
}
|
|
95
153
|
|
|
@@ -104,78 +162,93 @@ async function decrypt(payload, key) {
|
|
|
104
162
|
}
|
|
105
163
|
|
|
106
164
|
const msgsEl = document.getElementById("messages");
|
|
107
|
-
const
|
|
108
|
-
const
|
|
109
|
-
const
|
|
165
|
+
const scrollEl = document.getElementById("messages-scroll");
|
|
166
|
+
const headerName = document.getElementById("header-name");
|
|
167
|
+
const headerDesc = document.getElementById("header-desc");
|
|
110
168
|
|
|
111
|
-
function
|
|
112
|
-
function
|
|
169
|
+
function esc(s) { return s.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">"); }
|
|
170
|
+
function mentions(t) { return esc(t).replace(/@(\\w+)/g,'<span class="mention">@$1</span>'); }
|
|
113
171
|
|
|
114
|
-
function
|
|
115
|
-
msgsEl.innerHTML = "";
|
|
172
|
+
function render() {
|
|
116
173
|
const filtered = activeChannel === "all" ? allMessages : allMessages.filter(m => m.channel === activeChannel);
|
|
117
|
-
if (filtered.length
|
|
174
|
+
if (!filtered.length) { msgsEl.innerHTML = '<div class="empty">No messages yet</div>'; return; }
|
|
175
|
+
|
|
176
|
+
let html = "";
|
|
118
177
|
let lastSender = null;
|
|
178
|
+
let lastChannel = null;
|
|
179
|
+
|
|
119
180
|
for (const msg of filtered) {
|
|
120
|
-
const div = document.createElement("div");
|
|
121
|
-
const time = new Date(msg.timestamp).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"});
|
|
122
181
|
if (msg.type === "system") {
|
|
123
|
-
div
|
|
124
|
-
div.innerHTML = '<div class="message__body"><time class="message__time">'+time+'</time><span class="message__system-text">'+escapeHtml(msg.content)+'</span></div>';
|
|
182
|
+
html += '<div class="system-msg">' + esc(msg.content) + '</div>';
|
|
125
183
|
lastSender = null;
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const time = new Date(msg.timestamp).toLocaleTimeString([], {hour:"2-digit", minute:"2-digit"});
|
|
188
|
+
const color = getColor(msg.sender);
|
|
189
|
+
const isGrouped = lastSender === msg.sender && lastChannel === msg.channel;
|
|
190
|
+
|
|
191
|
+
if (!isGrouped) {
|
|
192
|
+
html += '<div class="conversation">';
|
|
193
|
+
html += '<div class="conversation__header">';
|
|
194
|
+
html += '<div class="conversation__avatar" style="background:'+color+'">'+msg.sender[0].toUpperCase()+'</div>';
|
|
195
|
+
html += '<div class="conversation__meta">';
|
|
196
|
+
html += '<span class="conversation__sender" style="color:'+color+'">@'+esc(msg.sender)+'</span>';
|
|
197
|
+
if (activeChannel === "all") html += '<span class="conversation__channel">#'+esc(msg.channel)+'</span>';
|
|
198
|
+
html += '<span class="conversation__time">'+time+'</span>';
|
|
199
|
+
html += '</div></div>';
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
html += '<div class="conversation__bubble'+(isGrouped?' conversation__bubble--grouped':'')+'">' + mentions(msg.content) + '</div>';
|
|
203
|
+
|
|
204
|
+
if (!isGrouped) {
|
|
205
|
+
// Close conversation div will be handled by next non-grouped or end
|
|
137
206
|
}
|
|
138
|
-
|
|
207
|
+
|
|
208
|
+
lastSender = msg.sender;
|
|
209
|
+
lastChannel = msg.channel;
|
|
139
210
|
}
|
|
140
|
-
|
|
211
|
+
|
|
212
|
+
msgsEl.innerHTML = html;
|
|
213
|
+
scrollEl.scrollTop = scrollEl.scrollHeight;
|
|
141
214
|
}
|
|
142
215
|
|
|
143
|
-
function
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
216
|
+
function renderSidebar() {
|
|
217
|
+
const el = document.getElementById("channel-list");
|
|
218
|
+
el.innerHTML = "";
|
|
219
|
+
const items = [{id:"all",label:"All channels",icon:"#"}];
|
|
220
|
+
for (const ch of CONFIG.channels) items.push({id:ch.channel,label:ch.channel,icon:"#"});
|
|
221
|
+
|
|
147
222
|
for (const item of items) {
|
|
148
223
|
const div = document.createElement("div");
|
|
149
|
-
div.className = "sidebar__channel"
|
|
150
|
-
div.innerHTML = '<span class="
|
|
151
|
-
div.onclick = () => {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
renderMessages();
|
|
224
|
+
div.className = "sidebar__channel"+(activeChannel===item.id?" active":"");
|
|
225
|
+
div.innerHTML = '<span class="icon">'+item.icon+'</span>'+esc(item.label);
|
|
226
|
+
div.onclick = () => {
|
|
227
|
+
activeChannel = item.id;
|
|
228
|
+
headerName.textContent = "# " + item.label;
|
|
229
|
+
headerDesc.textContent = item.id === "all" ? "All channels" : "";
|
|
230
|
+
renderSidebar();
|
|
231
|
+
render();
|
|
232
|
+
};
|
|
233
|
+
el.appendChild(div);
|
|
160
234
|
}
|
|
161
235
|
}
|
|
162
236
|
|
|
163
237
|
async function init() {
|
|
164
|
-
|
|
238
|
+
renderSidebar();
|
|
165
239
|
|
|
166
240
|
try {
|
|
167
241
|
const res = await fetch("/api/history");
|
|
168
242
|
const history = await res.json();
|
|
169
|
-
for (const
|
|
170
|
-
|
|
243
|
+
for (const m of history) allMessages.push(m);
|
|
244
|
+
render();
|
|
171
245
|
} catch(e) {}
|
|
172
246
|
|
|
173
247
|
const channels = {};
|
|
174
|
-
for (const ch of CONFIG.channels) {
|
|
175
|
-
channels[ch.channel] = {key:await deriveKey(ch.key),hash:await hashRoom(ch.key),name:ch.channel};
|
|
176
|
-
}
|
|
248
|
+
for (const ch of CONFIG.channels) channels[ch.channel] = {key:await deriveKey(ch.key),hash:await hashRoom(ch.key),name:ch.channel};
|
|
177
249
|
|
|
178
250
|
const client = mqtt.connect("wss://broker.emqx.io:8084/mqtt");
|
|
251
|
+
const statusEl = document.getElementById("status");
|
|
179
252
|
client.on("connect",()=>{statusEl.textContent="connected";statusEl.className="sidebar__status connected";for(const ch of Object.values(channels))client.subscribe("agentchannel/"+ch.hash+"/messages")});
|
|
180
253
|
client.on("close",()=>{statusEl.textContent="disconnected";statusEl.className="sidebar__status"});
|
|
181
254
|
|
|
@@ -187,8 +260,9 @@ async function init() {
|
|
|
187
260
|
try{
|
|
188
261
|
const msg=JSON.parse(await decrypt(payload.toString(),ch.key));
|
|
189
262
|
msg.channel=ch.name;
|
|
190
|
-
|
|
191
|
-
|
|
263
|
+
allMessages.push(msg);
|
|
264
|
+
render();
|
|
265
|
+
if(msg.sender!==CONFIG.name&&Notification.permission==="granted")new Notification("#"+ch.name+" @"+msg.sender,{body:msg.content});
|
|
192
266
|
}catch(e){}
|
|
193
267
|
}
|
|
194
268
|
}
|
package/dist/web.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web.js","sourceRoot":"","sources":["../src/web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAG3D,MAAM,WAAW,GAAG,GAAG,CAAC;AAExB,MAAM,
|
|
1
|
+
{"version":3,"file":"web.js","sourceRoot":"","sources":["../src/web.ts"],"names":[],"mappings":"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"}
|