@paramms/chat-widget 1.0.26 → 1.0.28
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/embed.js +4 -6
- package/dist/embed.js.map +1 -1
- package/dist/index.js +281 -280
- package/dist/index.js.map +1 -1
- package/dist/protocol/entities.d.ts +6 -0
- package/dist/protocol/frames.d.ts +14 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
var De = Object.defineProperty;
|
|
2
2
|
var _e = (s, e, t) => e in s ? De(s, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : s[e] = t;
|
|
3
3
|
var a = (s, e, t) => _e(s, typeof e != "symbol" ? e + "" : e, t);
|
|
4
|
-
import { p as $e, r as
|
|
4
|
+
import { p as $e, r as He, a as Re } from "./uid.js";
|
|
5
5
|
import { h as nn } from "./uid.js";
|
|
6
6
|
const Gt = (s) => s;
|
|
7
7
|
function Fe(s) {
|
|
@@ -36,8 +36,8 @@ function je(s, e, t) {
|
|
|
36
36
|
e[i++] = r >> 6 & 31 | 192;
|
|
37
37
|
else {
|
|
38
38
|
if (r >= 55296 && r <= 56319 && o < n) {
|
|
39
|
-
const
|
|
40
|
-
(
|
|
39
|
+
const h = s.charCodeAt(o);
|
|
40
|
+
(h & 64512) === 56320 && (++o, r = ((r & 1023) << 10) + (h & 1023) + 65536);
|
|
41
41
|
}
|
|
42
42
|
r & 4294901760 ? (e[i++] = r >> 18 & 7 | 240, e[i++] = r >> 12 & 63 | 128, e[i++] = r >> 6 & 63 | 128) : (e[i++] = r >> 12 & 15 | 224, e[i++] = r >> 6 & 63 | 128);
|
|
43
43
|
}
|
|
@@ -56,26 +56,26 @@ function Ve(s, e, t) {
|
|
|
56
56
|
s.length > Oe ? Ne(s, e, t) : je(s, e, t);
|
|
57
57
|
}
|
|
58
58
|
const We = 4096;
|
|
59
|
-
function
|
|
59
|
+
function Se(s, e, t) {
|
|
60
60
|
let n = e;
|
|
61
61
|
const i = n + t, o = [];
|
|
62
62
|
let r = "";
|
|
63
63
|
for (; n < i; ) {
|
|
64
|
-
const
|
|
65
|
-
if (!(
|
|
66
|
-
o.push(
|
|
67
|
-
else if ((
|
|
64
|
+
const h = s[n++];
|
|
65
|
+
if (!(h & 128))
|
|
66
|
+
o.push(h);
|
|
67
|
+
else if ((h & 224) === 192) {
|
|
68
68
|
const w = s[n++] & 63;
|
|
69
|
-
o.push((
|
|
70
|
-
} else if ((
|
|
69
|
+
o.push((h & 31) << 6 | w);
|
|
70
|
+
} else if ((h & 240) === 224) {
|
|
71
71
|
const w = s[n++] & 63, d = s[n++] & 63;
|
|
72
|
-
o.push((
|
|
73
|
-
} else if ((
|
|
72
|
+
o.push((h & 31) << 12 | w << 6 | d);
|
|
73
|
+
} else if ((h & 248) === 240) {
|
|
74
74
|
const w = s[n++] & 63, d = s[n++] & 63, v = s[n++] & 63;
|
|
75
|
-
let x = (
|
|
75
|
+
let x = (h & 7) << 18 | w << 12 | d << 6 | v;
|
|
76
76
|
x > 65535 && (x -= 65536, o.push(x >>> 10 & 1023 | 55296), x = 56320 | x & 1023), o.push(x);
|
|
77
77
|
} else
|
|
78
|
-
o.push(
|
|
78
|
+
o.push(h);
|
|
79
79
|
o.length >= We && (r += String.fromCharCode(...o), o.length = 0);
|
|
80
80
|
}
|
|
81
81
|
return o.length > 0 && (r += String.fromCharCode(...o)), r;
|
|
@@ -86,7 +86,7 @@ function Je(s, e, t) {
|
|
|
86
86
|
return Xe.decode(n);
|
|
87
87
|
}
|
|
88
88
|
function Ge(s, e, t) {
|
|
89
|
-
return t > Ye ? Je(s, e, t) :
|
|
89
|
+
return t > Ye ? Je(s, e, t) : Se(s, e, t);
|
|
90
90
|
}
|
|
91
91
|
class G {
|
|
92
92
|
constructor(e, t) {
|
|
@@ -106,16 +106,16 @@ class z extends Error {
|
|
|
106
106
|
});
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
|
-
const
|
|
109
|
+
const j = 4294967295;
|
|
110
110
|
function Ze(s, e, t) {
|
|
111
111
|
const n = t / 4294967296, i = t;
|
|
112
112
|
s.setUint32(e, n), s.setUint32(e + 4, i);
|
|
113
113
|
}
|
|
114
|
-
function
|
|
114
|
+
function Ie(s, e, t) {
|
|
115
115
|
const n = Math.floor(t / 4294967296), i = t;
|
|
116
116
|
s.setUint32(e, n), s.setUint32(e + 4, i);
|
|
117
117
|
}
|
|
118
|
-
function
|
|
118
|
+
function Ce(s, e) {
|
|
119
119
|
const t = s.getInt32(e), n = s.getUint32(e + 4);
|
|
120
120
|
return t * 4294967296 + n;
|
|
121
121
|
}
|
|
@@ -135,7 +135,7 @@ function it({ sec: s, nsec: e }) {
|
|
|
135
135
|
}
|
|
136
136
|
else {
|
|
137
137
|
const t = new Uint8Array(12), n = new DataView(t.buffer);
|
|
138
|
-
return n.setUint32(0, e),
|
|
138
|
+
return n.setUint32(0, e), Ie(n, 4, s), t;
|
|
139
139
|
}
|
|
140
140
|
}
|
|
141
141
|
function st(s) {
|
|
@@ -162,7 +162,7 @@ function rt(s) {
|
|
|
162
162
|
return { sec: i, nsec: o };
|
|
163
163
|
}
|
|
164
164
|
case 12: {
|
|
165
|
-
const t =
|
|
165
|
+
const t = Ce(e, 4), n = e.getUint32(0);
|
|
166
166
|
return { sec: t, nsec: n };
|
|
167
167
|
}
|
|
168
168
|
default:
|
|
@@ -462,7 +462,7 @@ class ce {
|
|
|
462
462
|
this.ensureBufferSizeToWrite(8), Ze(this.view, this.pos, e), this.pos += 8;
|
|
463
463
|
}
|
|
464
464
|
writeI64(e) {
|
|
465
|
-
this.ensureBufferSizeToWrite(8),
|
|
465
|
+
this.ensureBufferSizeToWrite(8), Ie(this.view, this.pos, e), this.pos += 8;
|
|
466
466
|
}
|
|
467
467
|
writeBigUint64(e) {
|
|
468
468
|
this.ensureBufferSizeToWrite(8), this.view.setBigUint64(this.pos, e), this.pos += 8;
|
|
@@ -496,8 +496,8 @@ class wt {
|
|
|
496
496
|
const i = this.caches[n - 1];
|
|
497
497
|
e: for (const o of i) {
|
|
498
498
|
const r = o.bytes;
|
|
499
|
-
for (let
|
|
500
|
-
if (r[
|
|
499
|
+
for (let h = 0; h < n; h++)
|
|
500
|
+
if (r[h] !== e[t + h])
|
|
501
501
|
continue e;
|
|
502
502
|
return o.str;
|
|
503
503
|
}
|
|
@@ -512,11 +512,11 @@ class wt {
|
|
|
512
512
|
if (i != null)
|
|
513
513
|
return this.hit++, i;
|
|
514
514
|
this.miss++;
|
|
515
|
-
const o =
|
|
515
|
+
const o = Se(e, t, n), r = Uint8Array.prototype.slice.call(e, t, t + n);
|
|
516
516
|
return this.store(r, o), o;
|
|
517
517
|
}
|
|
518
518
|
}
|
|
519
|
-
const re = "array",
|
|
519
|
+
const re = "array", O = "map_key", Ee = "map_value", xt = (s) => {
|
|
520
520
|
if (typeof s == "string" || typeof s == "number")
|
|
521
521
|
return s;
|
|
522
522
|
throw new z("The type of key must be string or number but " + typeof s);
|
|
@@ -538,7 +538,7 @@ class yt {
|
|
|
538
538
|
}
|
|
539
539
|
pushMapState(e) {
|
|
540
540
|
const t = this.getUninitializedStateFromPool();
|
|
541
|
-
t.type =
|
|
541
|
+
t.type = O, t.readCount = 0, t.size = e, t.map = {};
|
|
542
542
|
}
|
|
543
543
|
getUninitializedStateFromPool() {
|
|
544
544
|
if (this.stackHeadPosition++, this.stackHeadPosition === this.stack.length) {
|
|
@@ -562,7 +562,7 @@ class yt {
|
|
|
562
562
|
const n = e;
|
|
563
563
|
n.size = 0, n.array = void 0, n.position = 0, n.type = void 0;
|
|
564
564
|
}
|
|
565
|
-
if (e.type ===
|
|
565
|
+
if (e.type === O || e.type === Ee) {
|
|
566
566
|
const n = e;
|
|
567
567
|
n.size = 0, n.map = void 0, n.readCount = 0, n.type = void 0;
|
|
568
568
|
}
|
|
@@ -572,14 +572,14 @@ class yt {
|
|
|
572
572
|
this.stack.length = 0, this.stackHeadPosition = -1;
|
|
573
573
|
}
|
|
574
574
|
}
|
|
575
|
-
const
|
|
575
|
+
const q = -1, de = new DataView(new ArrayBuffer(0)), gt = new Uint8Array(de.buffer);
|
|
576
576
|
try {
|
|
577
577
|
de.getInt8(0);
|
|
578
578
|
} catch (s) {
|
|
579
579
|
if (!(s instanceof RangeError))
|
|
580
580
|
throw new Error("This module is not supported in the current JavaScript engine because DataView does not throw RangeError on out-of-bounds access");
|
|
581
581
|
}
|
|
582
|
-
const
|
|
582
|
+
const ye = new RangeError("Insufficient data"), bt = new wt();
|
|
583
583
|
class le {
|
|
584
584
|
constructor(e) {
|
|
585
585
|
a(this, "extensionCodec");
|
|
@@ -597,10 +597,10 @@ class le {
|
|
|
597
597
|
a(this, "pos", 0);
|
|
598
598
|
a(this, "view", de);
|
|
599
599
|
a(this, "bytes", gt);
|
|
600
|
-
a(this, "headByte",
|
|
600
|
+
a(this, "headByte", q);
|
|
601
601
|
a(this, "stack", new yt());
|
|
602
602
|
a(this, "entered", !1);
|
|
603
|
-
this.extensionCodec = (e == null ? void 0 : e.extensionCodec) ?? Q.defaultCodec, this.context = e == null ? void 0 : e.context, this.useBigInt64 = (e == null ? void 0 : e.useBigInt64) ?? !1, this.rawStrings = (e == null ? void 0 : e.rawStrings) ?? !1, this.maxStrLength = (e == null ? void 0 : e.maxStrLength) ??
|
|
603
|
+
this.extensionCodec = (e == null ? void 0 : e.extensionCodec) ?? Q.defaultCodec, this.context = e == null ? void 0 : e.context, this.useBigInt64 = (e == null ? void 0 : e.useBigInt64) ?? !1, this.rawStrings = (e == null ? void 0 : e.rawStrings) ?? !1, this.maxStrLength = (e == null ? void 0 : e.maxStrLength) ?? j, this.maxBinLength = (e == null ? void 0 : e.maxBinLength) ?? j, this.maxArrayLength = (e == null ? void 0 : e.maxArrayLength) ?? j, this.maxMapLength = (e == null ? void 0 : e.maxMapLength) ?? j, this.maxExtLength = (e == null ? void 0 : e.maxExtLength) ?? j, this.keyDecoder = (e == null ? void 0 : e.keyDecoder) !== void 0 ? e.keyDecoder : bt, this.mapKeyConverter = (e == null ? void 0 : e.mapKeyConverter) ?? xt;
|
|
604
604
|
}
|
|
605
605
|
clone() {
|
|
606
606
|
return new le({
|
|
@@ -617,14 +617,14 @@ class le {
|
|
|
617
617
|
});
|
|
618
618
|
}
|
|
619
619
|
reinitializeState() {
|
|
620
|
-
this.totalPos = 0, this.headByte =
|
|
620
|
+
this.totalPos = 0, this.headByte = q, this.stack.reset();
|
|
621
621
|
}
|
|
622
622
|
setBuffer(e) {
|
|
623
623
|
const t = oe(e);
|
|
624
624
|
this.bytes = t, this.view = new DataView(t.buffer, t.byteOffset, t.byteLength), this.pos = 0;
|
|
625
625
|
}
|
|
626
626
|
appendBuffer(e) {
|
|
627
|
-
if (this.headByte ===
|
|
627
|
+
if (this.headByte === q && !this.hasRemaining(1))
|
|
628
628
|
this.setBuffer(e);
|
|
629
629
|
else {
|
|
630
630
|
const t = this.bytes.subarray(this.pos), n = oe(e), i = new Uint8Array(t.length + n.length);
|
|
@@ -673,10 +673,10 @@ class le {
|
|
|
673
673
|
try {
|
|
674
674
|
this.entered = !0;
|
|
675
675
|
let t = !1, n;
|
|
676
|
-
for await (const
|
|
676
|
+
for await (const h of e) {
|
|
677
677
|
if (t)
|
|
678
678
|
throw this.entered = !1, this.createExtraByteError(this.totalPos);
|
|
679
|
-
this.appendBuffer(
|
|
679
|
+
this.appendBuffer(h);
|
|
680
680
|
try {
|
|
681
681
|
n = this.doDecodeSync(), t = !0;
|
|
682
682
|
} catch (w) {
|
|
@@ -856,15 +856,15 @@ class le {
|
|
|
856
856
|
t = i.array, n.release(i);
|
|
857
857
|
else
|
|
858
858
|
continue e;
|
|
859
|
-
else if (i.type ===
|
|
859
|
+
else if (i.type === O) {
|
|
860
860
|
if (t === "__proto__")
|
|
861
861
|
throw new z("The key __proto__ is not allowed");
|
|
862
|
-
i.key = this.mapKeyConverter(t), i.type =
|
|
862
|
+
i.key = this.mapKeyConverter(t), i.type = Ee;
|
|
863
863
|
continue e;
|
|
864
864
|
} else if (i.map[i.key] = t, i.readCount++, i.readCount === i.size)
|
|
865
865
|
t = i.map, n.release(i);
|
|
866
866
|
else {
|
|
867
|
-
i.key = null, i.type =
|
|
867
|
+
i.key = null, i.type = O;
|
|
868
868
|
continue e;
|
|
869
869
|
}
|
|
870
870
|
}
|
|
@@ -872,10 +872,10 @@ class le {
|
|
|
872
872
|
}
|
|
873
873
|
}
|
|
874
874
|
readHeadByte() {
|
|
875
|
-
return this.headByte ===
|
|
875
|
+
return this.headByte === q && (this.headByte = this.readU8()), this.headByte;
|
|
876
876
|
}
|
|
877
877
|
complete() {
|
|
878
|
-
this.headByte =
|
|
878
|
+
this.headByte = q;
|
|
879
879
|
}
|
|
880
880
|
readArraySize() {
|
|
881
881
|
const e = this.readHeadByte();
|
|
@@ -912,13 +912,13 @@ class le {
|
|
|
912
912
|
if (e > this.maxStrLength)
|
|
913
913
|
throw new z(`Max length exceeded: UTF-8 byte length (${e}) > maxStrLength (${this.maxStrLength})`);
|
|
914
914
|
if (this.bytes.byteLength < this.pos + t + e)
|
|
915
|
-
throw
|
|
915
|
+
throw ye;
|
|
916
916
|
const n = this.pos + t;
|
|
917
917
|
let i;
|
|
918
918
|
return this.stateIsMapKey() && ((o = this.keyDecoder) != null && o.canBeCached(e)) ? i = this.keyDecoder.decode(this.bytes, n, e) : i = Ge(this.bytes, n, e), this.pos += t + e, i;
|
|
919
919
|
}
|
|
920
920
|
stateIsMapKey() {
|
|
921
|
-
return this.stack.length > 0 ? this.stack.top().type ===
|
|
921
|
+
return this.stack.length > 0 ? this.stack.top().type === O : !1;
|
|
922
922
|
}
|
|
923
923
|
/**
|
|
924
924
|
* @throws {@link RangeError}
|
|
@@ -927,7 +927,7 @@ class le {
|
|
|
927
927
|
if (e > this.maxBinLength)
|
|
928
928
|
throw new z(`Max length exceeded: bin length (${e}) > maxBinLength (${this.maxBinLength})`);
|
|
929
929
|
if (!this.hasRemaining(e + t))
|
|
930
|
-
throw
|
|
930
|
+
throw ye;
|
|
931
931
|
const n = this.pos + t, i = this.bytes.subarray(n, n + e);
|
|
932
932
|
return this.pos += t + e, i;
|
|
933
933
|
}
|
|
@@ -979,7 +979,7 @@ class le {
|
|
|
979
979
|
return this.pos += 8, e;
|
|
980
980
|
}
|
|
981
981
|
readI64() {
|
|
982
|
-
const e =
|
|
982
|
+
const e = Ce(this.view, this.pos);
|
|
983
983
|
return this.pos += 8, e;
|
|
984
984
|
}
|
|
985
985
|
readU64AsBigInt() {
|
|
@@ -1017,7 +1017,15 @@ const vt = /* @__PURE__ */ new Set([
|
|
|
1017
1017
|
"pubkey",
|
|
1018
1018
|
"ping",
|
|
1019
1019
|
"annotate",
|
|
1020
|
-
"annotate_clear"
|
|
1020
|
+
"annotate_clear",
|
|
1021
|
+
"uploadPrekeys",
|
|
1022
|
+
"fetchPrekey",
|
|
1023
|
+
"assign",
|
|
1024
|
+
"tag",
|
|
1025
|
+
"note",
|
|
1026
|
+
"agent_status",
|
|
1027
|
+
"subscribe_inbox",
|
|
1028
|
+
"unsubscribe_inbox"
|
|
1021
1029
|
]);
|
|
1022
1030
|
function kt(s) {
|
|
1023
1031
|
return vt.has(s.type);
|
|
@@ -1179,14 +1187,14 @@ class Ct {
|
|
|
1179
1187
|
this.byId.set(e.id, t ? { ...t, ...e } : e), e.seq > this._maxSeq && (this._maxSeq = e.seq), this._sorted = null;
|
|
1180
1188
|
}
|
|
1181
1189
|
markOwnStatus(e, t) {
|
|
1182
|
-
const n =
|
|
1190
|
+
const n = ge(t);
|
|
1183
1191
|
let i = !1;
|
|
1184
1192
|
for (const [o, r] of this.byId)
|
|
1185
|
-
r.senderId !== this.me || r.seq <= 0 || r.seq > e ||
|
|
1193
|
+
r.senderId !== this.me || r.seq <= 0 || r.seq > e || ge(r.status) >= n || (this.byId.set(o, { ...r, status: t }), i = !0);
|
|
1186
1194
|
i && (this._sorted = null);
|
|
1187
1195
|
}
|
|
1188
1196
|
}
|
|
1189
|
-
function
|
|
1197
|
+
function ge(s) {
|
|
1190
1198
|
switch (s) {
|
|
1191
1199
|
case "read":
|
|
1192
1200
|
return 3;
|
|
@@ -1214,7 +1222,7 @@ class Et {
|
|
|
1214
1222
|
var n, i;
|
|
1215
1223
|
if (this.state === "connecting" || this.state === "open") return;
|
|
1216
1224
|
this.stopped = !1, this.state = "connecting", this.authed = !1, (i = (n = this.opts).onStatusChange) == null || i.call(n, this.attempt > 0 ? "reconnecting" : "connecting");
|
|
1217
|
-
const t = (this.opts.socketFactory ??
|
|
1225
|
+
const t = (this.opts.socketFactory ?? Pt)(this.opts.url);
|
|
1218
1226
|
t.binaryType = "arraybuffer", this.socket = t, t.onopen = () => {
|
|
1219
1227
|
this.raw({ type: "auth", token: this.opts.token });
|
|
1220
1228
|
}, t.onmessage = (o) => {
|
|
@@ -1283,23 +1291,19 @@ class Et {
|
|
|
1283
1291
|
this.attempt++, this.attempt >= 3 && !this.everAuthed && ((o = (i = this.opts).onStatusChange) == null || o.call(i, "reconnecting", "Can't reach chat — retrying…")), this.timer = setTimeout(() => this.connect(), n);
|
|
1284
1292
|
}
|
|
1285
1293
|
}
|
|
1286
|
-
const Tt = /* @__PURE__ */ new Set(["UNAUTHORIZED"
|
|
1294
|
+
const Tt = /* @__PURE__ */ new Set(["UNAUTHORIZED"]);
|
|
1287
1295
|
function Ut(s) {
|
|
1288
1296
|
switch (s) {
|
|
1289
1297
|
case "UNAUTHORIZED":
|
|
1290
1298
|
return "Chat unavailable — sign-in/token was rejected";
|
|
1291
|
-
case "FORBIDDEN":
|
|
1292
|
-
return "Chat unavailable";
|
|
1293
|
-
case "NOT_FOUND":
|
|
1294
|
-
return "This chat isn't available";
|
|
1295
1299
|
default:
|
|
1296
1300
|
return "Chat unavailable";
|
|
1297
1301
|
}
|
|
1298
1302
|
}
|
|
1299
|
-
function
|
|
1303
|
+
function Pt(s) {
|
|
1300
1304
|
return new WebSocket(s);
|
|
1301
1305
|
}
|
|
1302
|
-
const
|
|
1306
|
+
const be = 200, Bt = 7 * 864e5;
|
|
1303
1307
|
class At {
|
|
1304
1308
|
constructor(e) {
|
|
1305
1309
|
a(this, "key");
|
|
@@ -1310,7 +1314,7 @@ class At {
|
|
|
1310
1314
|
try {
|
|
1311
1315
|
const e = localStorage.getItem(this.key);
|
|
1312
1316
|
if (!e) return [];
|
|
1313
|
-
const t = JSON.parse(e), n = Date.now() -
|
|
1317
|
+
const t = JSON.parse(e), n = Date.now() - Bt, i = t.filter((o) => o.ts >= n);
|
|
1314
1318
|
return i.length !== t.length && this.save(i), i;
|
|
1315
1319
|
} catch {
|
|
1316
1320
|
return [];
|
|
@@ -1319,7 +1323,7 @@ class At {
|
|
|
1319
1323
|
add(e) {
|
|
1320
1324
|
try {
|
|
1321
1325
|
const t = this.load();
|
|
1322
|
-
t.push(e), this.save(t.length >
|
|
1326
|
+
t.push(e), this.save(t.length > be ? t.slice(t.length - be) : t);
|
|
1323
1327
|
} catch {
|
|
1324
1328
|
}
|
|
1325
1329
|
}
|
|
@@ -1350,18 +1354,18 @@ function ae(s) {
|
|
|
1350
1354
|
for (let i = 0; i < e.length; i++) n[i] = e.charCodeAt(i);
|
|
1351
1355
|
return n;
|
|
1352
1356
|
}
|
|
1353
|
-
async function
|
|
1357
|
+
async function N() {
|
|
1354
1358
|
const s = await C().generateKey({ name: "ECDH", namedCurve: "P-256" }, !0, ["deriveKey", "deriveBits"]);
|
|
1355
1359
|
return { publicKey: s.publicKey, privateKey: s.privateKey };
|
|
1356
1360
|
}
|
|
1357
1361
|
async function _(s) {
|
|
1358
1362
|
return ee(await C().exportKey("raw", s));
|
|
1359
1363
|
}
|
|
1360
|
-
async function
|
|
1364
|
+
async function R(s) {
|
|
1361
1365
|
return C().importKey("raw", ae(s), { name: "ECDH", namedCurve: "P-256" }, !1, []);
|
|
1362
1366
|
}
|
|
1363
1367
|
async function Kt(s, e) {
|
|
1364
|
-
const t = await
|
|
1368
|
+
const t = await R(e);
|
|
1365
1369
|
return C().deriveKey(
|
|
1366
1370
|
{ name: "ECDH", public: t },
|
|
1367
1371
|
s,
|
|
@@ -1383,12 +1387,12 @@ async function Mt(s) {
|
|
|
1383
1387
|
try {
|
|
1384
1388
|
const i = (t = globalThis.localStorage) == null ? void 0 : t.getItem(s);
|
|
1385
1389
|
if (i) {
|
|
1386
|
-
const { pub: o, priv: r } = JSON.parse(i),
|
|
1387
|
-
return { publicKey:
|
|
1390
|
+
const { pub: o, priv: r } = JSON.parse(i), h = await C().importKey("jwk", o, { name: "ECDH", namedCurve: "P-256" }, !0, []), w = await C().importKey("jwk", r, { name: "ECDH", namedCurve: "P-256" }, !0, ["deriveKey", "deriveBits"]);
|
|
1391
|
+
return { publicKey: h, privateKey: w };
|
|
1388
1392
|
}
|
|
1389
1393
|
} catch {
|
|
1390
1394
|
}
|
|
1391
|
-
const e = await
|
|
1395
|
+
const e = await N();
|
|
1392
1396
|
try {
|
|
1393
1397
|
const i = await C().exportKey("jwk", e.publicKey), o = await C().exportKey("jwk", e.privateKey);
|
|
1394
1398
|
(n = globalThis.localStorage) == null || n.setItem(s, JSON.stringify({ pub: i, priv: o }));
|
|
@@ -1401,7 +1405,7 @@ async function Dt(s, e) {
|
|
|
1401
1405
|
return ee(n);
|
|
1402
1406
|
}
|
|
1403
1407
|
async function _t() {
|
|
1404
|
-
const s = await
|
|
1408
|
+
const s = await N(), e = await C().generateKey({ name: "ECDSA", namedCurve: "P-256" }, !0, ["sign", "verify"]);
|
|
1405
1409
|
return {
|
|
1406
1410
|
ecdhKP: s,
|
|
1407
1411
|
ecdsaKP: { publicKey: e.publicKey, privateKey: e.privateKey },
|
|
@@ -1409,14 +1413,14 @@ async function _t() {
|
|
|
1409
1413
|
sigPublicKeyB64: await _(e.publicKey)
|
|
1410
1414
|
};
|
|
1411
1415
|
}
|
|
1412
|
-
async function
|
|
1416
|
+
async function me(s) {
|
|
1413
1417
|
var t, n;
|
|
1414
1418
|
try {
|
|
1415
1419
|
const i = (t = globalThis.localStorage) == null ? void 0 : t.getItem(`${s}-identity`);
|
|
1416
1420
|
if (i) {
|
|
1417
|
-
const o = JSON.parse(i), r = await C().importKey("jwk", o.ecdhPub, { name: "ECDH", namedCurve: "P-256" }, !0, []),
|
|
1421
|
+
const o = JSON.parse(i), r = await C().importKey("jwk", o.ecdhPub, { name: "ECDH", namedCurve: "P-256" }, !0, []), h = await C().importKey("jwk", o.ecdhPriv, { name: "ECDH", namedCurve: "P-256" }, !0, ["deriveKey", "deriveBits"]), w = await C().importKey("jwk", o.ecdsaPub, { name: "ECDSA", namedCurve: "P-256" }, !0, ["verify"]), d = await C().importKey("jwk", o.ecdsaPriv, { name: "ECDSA", namedCurve: "P-256" }, !0, ["sign"]);
|
|
1418
1422
|
return {
|
|
1419
|
-
ecdhKP: { publicKey: r, privateKey:
|
|
1423
|
+
ecdhKP: { publicKey: r, privateKey: h },
|
|
1420
1424
|
ecdsaKP: { publicKey: w, privateKey: d },
|
|
1421
1425
|
publicKeyB64: await _(r),
|
|
1422
1426
|
sigPublicKeyB64: await _(w)
|
|
@@ -1426,31 +1430,31 @@ async function be(s) {
|
|
|
1426
1430
|
}
|
|
1427
1431
|
const e = await _t();
|
|
1428
1432
|
try {
|
|
1429
|
-
const i = await C().exportKey("jwk", e.ecdhKP.publicKey), o = await C().exportKey("jwk", e.ecdhKP.privateKey), r = await C().exportKey("jwk", e.ecdsaKP.publicKey),
|
|
1430
|
-
(n = globalThis.localStorage) == null || n.setItem(`${s}-identity`, JSON.stringify({ ecdhPub: i, ecdhPriv: o, ecdsaPub: r, ecdsaPriv:
|
|
1433
|
+
const i = await C().exportKey("jwk", e.ecdhKP.publicKey), o = await C().exportKey("jwk", e.ecdhKP.privateKey), r = await C().exportKey("jwk", e.ecdsaKP.publicKey), h = await C().exportKey("jwk", e.ecdsaKP.privateKey);
|
|
1434
|
+
(n = globalThis.localStorage) == null || n.setItem(`${s}-identity`, JSON.stringify({ ecdhPub: i, ecdhPriv: o, ecdsaPub: r, ecdsaPriv: h }));
|
|
1431
1435
|
} catch {
|
|
1432
1436
|
}
|
|
1433
1437
|
return e;
|
|
1434
1438
|
}
|
|
1435
1439
|
async function $t(s, e) {
|
|
1436
|
-
const t = await
|
|
1437
|
-
return { sharedKey: await
|
|
1440
|
+
const t = await N(), n = await _(t.publicKey), i = await R(e.identityKey), o = await R(e.signedPrekey), r = e.oneTimePrekey ? await R(e.oneTimePrekey) : null, h = await D(s.privateKey, o), w = await D(t.privateKey, i), d = await D(t.privateKey, o), v = r ? await D(t.privateKey, r) : null, x = Te(h, w, d, ...v ? [v] : []);
|
|
1441
|
+
return { sharedKey: await Ue(x), ephemeralPublicKey: n };
|
|
1438
1442
|
}
|
|
1439
|
-
async function
|
|
1440
|
-
const o = await
|
|
1441
|
-
return
|
|
1443
|
+
async function Ht(s, e, t, n, i) {
|
|
1444
|
+
const o = await R(t), r = await R(n), h = await D(e.privateKey, o), w = await D(s.privateKey, r), d = await D(e.privateKey, r), v = i ? await D(i.privateKey, r) : null, x = Te(h, w, d, ...v ? [v] : []);
|
|
1445
|
+
return Ue(x);
|
|
1442
1446
|
}
|
|
1443
1447
|
async function D(s, e) {
|
|
1444
1448
|
return C().deriveBits({ name: "ECDH", public: e }, s, 256);
|
|
1445
1449
|
}
|
|
1446
|
-
function
|
|
1450
|
+
function Te(...s) {
|
|
1447
1451
|
const e = s.reduce((i, o) => i + o.byteLength, 0), t = new Uint8Array(e);
|
|
1448
1452
|
let n = 0;
|
|
1449
1453
|
for (const i of s)
|
|
1450
1454
|
t.set(new Uint8Array(i), n), n += i.byteLength;
|
|
1451
1455
|
return t.buffer;
|
|
1452
1456
|
}
|
|
1453
|
-
async function
|
|
1457
|
+
async function Ue(s) {
|
|
1454
1458
|
const e = await C().importKey("raw", s, "HKDF", !1, ["deriveKey"]);
|
|
1455
1459
|
return C().deriveKey(
|
|
1456
1460
|
{ name: "HKDF", hash: "SHA-256", salt: new Uint8Array(32), info: new TextEncoder().encode("ObjectChat X3DH v1") },
|
|
@@ -1460,7 +1464,7 @@ async function Te(s) {
|
|
|
1460
1464
|
["encrypt", "decrypt"]
|
|
1461
1465
|
);
|
|
1462
1466
|
}
|
|
1463
|
-
const
|
|
1467
|
+
const Rt = 20;
|
|
1464
1468
|
class Ft {
|
|
1465
1469
|
constructor(e) {
|
|
1466
1470
|
// Live ECDH mode state
|
|
@@ -1492,8 +1496,8 @@ class Ft {
|
|
|
1492
1496
|
/** X3DH: Generate identity key, signed prekey, and OTP prekeys.
|
|
1493
1497
|
* Returns the upload frame payload the caller should send to the server. */
|
|
1494
1498
|
async initX3DH() {
|
|
1495
|
-
this.identityKP = await
|
|
1496
|
-
for (let i = 0; i <
|
|
1499
|
+
this.identityKP = await me(this.storageKey), this.signedPreKP = await N(), this.signedPrekeyId = `spk-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
1500
|
+
for (let i = 0; i < Rt; i++) this.otpKeys.push(await N());
|
|
1497
1501
|
const e = await _(this.signedPreKP.publicKey), t = await Dt(this.identityKP.ecdsaKP.privateKey, this.signedPreKP.publicKey), n = await Promise.all(this.otpKeys.map((i) => _(i.publicKey)));
|
|
1498
1502
|
return {
|
|
1499
1503
|
identityKey: this.identityKP.publicKeyB64,
|
|
@@ -1506,7 +1510,7 @@ class Ft {
|
|
|
1506
1510
|
/** X3DH sender: given a recipient's prekey bundle, derive the shared key and
|
|
1507
1511
|
* return the init message fields to embed in the first encrypted message. */
|
|
1508
1512
|
async x3dhSendTo(e) {
|
|
1509
|
-
this.identityKP || (this.identityKP = await
|
|
1513
|
+
this.identityKP || (this.identityKP = await me(this.storageKey));
|
|
1510
1514
|
const { sharedKey: t, ephemeralPublicKey: n } = await $t(this.identityKP.ecdhKP, e);
|
|
1511
1515
|
return this.x3dhShared = t, { ephemeralKey: n, spkId: e.signedPrekeyId, usedOTP: !!e.oneTimePrekey, senderIK: this.identityKP.publicKeyB64 };
|
|
1512
1516
|
}
|
|
@@ -1517,7 +1521,7 @@ class Ft {
|
|
|
1517
1521
|
return;
|
|
1518
1522
|
}
|
|
1519
1523
|
const i = this.otpKeys.shift();
|
|
1520
|
-
this.x3dhShared = await
|
|
1524
|
+
this.x3dhShared = await Ht(this.identityKP.ecdhKP, this.signedPreKP, e, t, i);
|
|
1521
1525
|
}
|
|
1522
1526
|
/** Flush pending X3DH derivation after initX3DH() completes. */
|
|
1523
1527
|
async flushPendingX3DH() {
|
|
@@ -1562,7 +1566,7 @@ function jt(s) {
|
|
|
1562
1566
|
const e = s;
|
|
1563
1567
|
return !e.x3dhEK || !e.x3dhSPK || !e.x3dhIK ? null : { x3dhEK: e.x3dhEK, x3dhSPK: e.x3dhSPK, x3dhIK: e.x3dhIK };
|
|
1564
1568
|
}
|
|
1565
|
-
const
|
|
1569
|
+
const ve = "objectchat-widget-styles", qt = ["👍", "❤️", "😂", "😮", "😢", "🙏"], Ot = `
|
|
1566
1570
|
.ocw { --ocw-accent:#4F63F5; --ocw-bg:#f3efe9; --ocw-card:#fff; --ocw-line:#ececec; --ocw-ink:#1c1b1a; --ocw-mut:#9b9690;
|
|
1567
1571
|
position:relative;
|
|
1568
1572
|
display:flex; flex-direction:column; height:100%; min-height:320px; background:var(--ocw-bg);
|
|
@@ -1723,9 +1727,9 @@ const me = "objectchat-widget-styles", qt = ["👍", "❤️", "😂", "😮", "
|
|
|
1723
1727
|
.ocw-translated-tag { font-size:10px; color:var(--ocw-mut); margin-top:2px; }
|
|
1724
1728
|
`;
|
|
1725
1729
|
function Nt() {
|
|
1726
|
-
if (typeof document > "u" || document.getElementById(
|
|
1730
|
+
if (typeof document > "u" || document.getElementById(ve)) return;
|
|
1727
1731
|
const s = document.createElement("style");
|
|
1728
|
-
s.id =
|
|
1732
|
+
s.id = ve, s.textContent = Ot, document.head.appendChild(s);
|
|
1729
1733
|
}
|
|
1730
1734
|
function c(s, e, t) {
|
|
1731
1735
|
const n = document.createElement(s);
|
|
@@ -1788,17 +1792,17 @@ class Wt {
|
|
|
1788
1792
|
a(this, "translationCache", /* @__PURE__ */ new Map());
|
|
1789
1793
|
a(this, "showingTranslation", /* @__PURE__ */ new Set());
|
|
1790
1794
|
a(this, "subjectBuilt", !1);
|
|
1791
|
-
var m,
|
|
1795
|
+
var m, y, U, A, P, K, b, S, M;
|
|
1792
1796
|
this.root = e, this.me = t, this.h = n, this.cfg = i, Nt(), e.replaceChildren(), e.classList.add("ocw"), i.accent && e.style.setProperty("--ocw-accent", i.accent);
|
|
1793
1797
|
const o = c("div", "ocw-head"), r = c("div", "ocw-avatar");
|
|
1794
1798
|
if ((m = i.userInfo) != null && m.avatar) {
|
|
1795
1799
|
const k = document.createElement("img");
|
|
1796
1800
|
k.src = i.userInfo.avatar, k.alt = i.userInfo.name ?? "You", k.style.cssText = "width:100%;height:100%;border-radius:50%;object-fit:cover", r.append(k);
|
|
1797
1801
|
} else
|
|
1798
|
-
r.textContent = (
|
|
1802
|
+
r.textContent = (y = i.userInfo) != null && y.name ? i.userInfo.name[0].toUpperCase() : "🧑";
|
|
1799
1803
|
o.append(r);
|
|
1800
|
-
const
|
|
1801
|
-
this.headerName = c("div", "ocw-head-name", ((U = i.subject) == null ? void 0 : U.ownerLabel) ?? ((A = i.subject) == null ? void 0 : A.title) ?? ""),
|
|
1804
|
+
const h = c("div", "ocw-head-main");
|
|
1805
|
+
this.headerName = c("div", "ocw-head-name", ((U = i.subject) == null ? void 0 : U.ownerLabel) ?? ((A = i.subject) == null ? void 0 : A.title) ?? ""), h.append(this.headerName), (P = i.subject) != null && P.subtitle && h.append(c("div", "ocw-head-meta", i.subject.subtitle)), o.append(h), this.statusBadge = c("span", "ocw-badge", ((K = i.subject) == null ? void 0 : K.status) ?? ""), (b = i.subject) != null && b.status || (this.statusBadge.style.display = "none"), o.append(this.statusBadge), this.e2eBadge = c("span", "ocw-e2e", "🔒 E2E"), this.e2eBadge.style.display = "none", o.append(this.e2eBadge), this.connStatus = c("span", "ocw-conn-status"), this.connStatus.style.display = "none", o.append(this.connStatus), this.cobrowseBtn = c("button", "ocw-menu ocw-cobrowse-btn", "🖍"), this.cobrowseBtn.title = "Shared whiteboard — draw to point things out together", this.cobrowseBtn.addEventListener("click", () => {
|
|
1802
1806
|
this.cobrowseActive = !this.cobrowseActive, this.updateCobrowseUI();
|
|
1803
1807
|
}), o.append(this.cobrowseBtn), o.append(c("button", "ocw-menu", "⋯")), this.chips = c("div", "ocw-chiprow"), this.scroll = c("div", "ocw-scroll"), this.subjectCard = c("div", "ocw-subject"), this.typing = c("div", "ocw-typing");
|
|
1804
1808
|
const w = c("div", "ocw-typing-bubble");
|
|
@@ -1821,15 +1825,15 @@ class Wt {
|
|
|
1821
1825
|
var k;
|
|
1822
1826
|
(k = x.files) != null && k[0] && this.h.onAttach && this.h.onAttach(x.files[0]), x.value = "";
|
|
1823
1827
|
});
|
|
1824
|
-
const
|
|
1825
|
-
|
|
1826
|
-
const
|
|
1827
|
-
((M = i.i18n) == null ? void 0 : M.poweredBy) !== void 0 ?
|
|
1828
|
+
const u = c("div", "ocw-input");
|
|
1829
|
+
u.append(v, x, this.input, d);
|
|
1830
|
+
const p = c("div", "ocw-footer");
|
|
1831
|
+
((M = i.i18n) == null ? void 0 : M.poweredBy) !== void 0 ? p.textContent = i.i18n.poweredBy : p.innerHTML = 'Powered by <a href="https://relay.paramms.com" target="_blank" rel="noopener">Relay</a>', this.footer = p, e.append(o, this.chips, this.scroll, this.typing, this.quick, this.formHost, this.csatPanel, this.offlinePanel, u, this.footer), this.cobrowseCanvas = c("canvas", "ocw-cobrowse-canvas"), this.cobrowseToolbar = c("div", "ocw-cobrowse-toolbar");
|
|
1828
1832
|
for (const k of ["#f5713c", "#1c1b1a", "#2563eb", "#16a34a", "#dc2626"]) {
|
|
1829
1833
|
const T = c("button", "ocw-cobrowse-swatch");
|
|
1830
1834
|
T.style.background = k, T.type = "button", k === this.cobrowseColor && T.classList.add("sel"), T.addEventListener("click", () => {
|
|
1831
1835
|
this.cobrowseColor = k;
|
|
1832
|
-
for (const
|
|
1836
|
+
for (const V of this.cobrowseToolbar.querySelectorAll(".ocw-cobrowse-swatch")) V.classList.remove("sel");
|
|
1833
1837
|
T.classList.add("sel");
|
|
1834
1838
|
}), this.cobrowseToolbar.append(T);
|
|
1835
1839
|
}
|
|
@@ -1869,26 +1873,26 @@ class Wt {
|
|
|
1869
1873
|
render(e) {
|
|
1870
1874
|
var d, v, x;
|
|
1871
1875
|
if (this.storeRef = e, this.cobrowseBtn.classList.toggle("show", !!e.subject), !e.subject && this.cobrowseActive && (this.cobrowseActive = !1, this.updateCobrowseUI()), this.cobrowseActive && e.annotationVersion !== this.lastAnnotationVersion && (this.lastAnnotationVersion = e.annotationVersion, this.resizeCobrowseCanvas(), this.redrawCobrowse()), e.accent && this.root.style.setProperty("--ocw-accent", e.accent), this.e2eBadge.style.display = e.e2e ? "inline-flex" : "none", this.buildSubjectCard(e), e.subject) {
|
|
1872
|
-
const
|
|
1873
|
-
|
|
1876
|
+
const u = (d = this.cfg.subject) == null ? void 0 : d.ownerLabel;
|
|
1877
|
+
u && (this.headerName.textContent = u);
|
|
1874
1878
|
}
|
|
1875
1879
|
this.quick.style.display = e.messages().length === 0 ? "flex" : "none", this.chips.replaceChildren();
|
|
1876
1880
|
const t = e.visibleActions();
|
|
1877
1881
|
this.chips.style.display = t.length ? "flex" : "none";
|
|
1878
|
-
for (const
|
|
1882
|
+
for (const u of t) this.chips.append(this.chipEl(u));
|
|
1879
1883
|
const n = this.scroll.scrollHeight, i = this.scroll.scrollTop;
|
|
1880
1884
|
if (this.scroll.replaceChildren(), this.subjectCard.childNodes.length && this.scroll.append(this.subjectCard), e.hasMoreHistory) {
|
|
1881
|
-
const
|
|
1882
|
-
|
|
1885
|
+
const u = c("div", "ocw-load-more");
|
|
1886
|
+
u.textContent = "↑ Loading earlier messages…", u.style.pointerEvents = "none", this.scroll.append(u);
|
|
1883
1887
|
}
|
|
1884
1888
|
let o = 0;
|
|
1885
|
-
for (const
|
|
1886
|
-
this.scroll.append(this.messageEl(
|
|
1889
|
+
for (const u of e.messages())
|
|
1890
|
+
this.scroll.append(this.messageEl(u, e)), u.senderId !== this.me && u.seq > o && (o = u.seq);
|
|
1887
1891
|
i > 20 ? this.scroll.scrollTop = this.scroll.scrollHeight - n + i : this.scroll.scrollTop = this.scroll.scrollHeight, o > 0 && this.h.onReadUpTo(o);
|
|
1888
1892
|
const r = [...e.typing];
|
|
1889
1893
|
this.typing.classList.toggle("active", r.length > 0);
|
|
1890
|
-
const
|
|
1891
|
-
|
|
1894
|
+
const h = this.typing.querySelector(".ocw-typing-bubble");
|
|
1895
|
+
h && h.setAttribute("aria-label", r.length ? "typing" : ""), this.footer.style.display = e.whiteLabel ? "none" : "block", e.offline ? (this.offlinePanel.style.display === "none" && this.buildOfflinePanel(e.offlineMessage), this.offlinePanel.style.display = "block", (v = this.root.querySelector(".ocw-input")) == null || v.style.setProperty("display", "none")) : (this.offlinePanel.style.display = "none", (x = this.root.querySelector(".ocw-input")) == null || x.style.removeProperty("display"));
|
|
1892
1896
|
const w = ["resolved", "closed", "sold", "issued", "checked_out"];
|
|
1893
1897
|
this.h.onCsat && !this.csatSubmitted && w.includes(e.state) && e.messages().length > 0 && (this.csatPanel.style.display === "none" && this.buildCsatPanel(), this.csatPanel.style.display = "block");
|
|
1894
1898
|
}
|
|
@@ -1902,8 +1906,8 @@ class Wt {
|
|
|
1902
1906
|
this.connStatus.className = `ocw-conn-status${n ? " err" : e === "reconnecting" ? " warn" : ""}`, this.connStatus.textContent = n ? `⚠ ${t ?? "Chat unavailable"}` : e === "reconnecting" ? t ?? "↻ reconnecting…" : "● connecting…";
|
|
1903
1907
|
}
|
|
1904
1908
|
buildOfflinePanel(e) {
|
|
1905
|
-
var
|
|
1906
|
-
this.offlinePanel.replaceChildren(), this.offlinePanel.append(c("div", "ocw-offline-icon", "🌙")), this.offlinePanel.append(c("div", "ocw-offline-title", ((
|
|
1909
|
+
var h;
|
|
1910
|
+
this.offlinePanel.replaceChildren(), this.offlinePanel.append(c("div", "ocw-offline-icon", "🌙")), this.offlinePanel.append(c("div", "ocw-offline-title", ((h = this.cfg.i18n) == null ? void 0 : h.offline) ?? "We're offline right now")), this.offlinePanel.append(c("div", "ocw-offline-msg", e || "Leave your details and we'll get back to you soon."));
|
|
1907
1911
|
const t = c("div", "ocw-offline-form"), n = c("input", "ocw-offline-input");
|
|
1908
1912
|
n.placeholder = "Your name", n.type = "text";
|
|
1909
1913
|
const i = c("input", "ocw-offline-input");
|
|
@@ -1960,7 +1964,7 @@ Message: ${o.value}`), this.offlinePanel.replaceChildren(c("div", "ocw-offline-t
|
|
|
1960
1964
|
bindCobrowsePointerEvents() {
|
|
1961
1965
|
let e = !1, t = [];
|
|
1962
1966
|
const n = (r) => {
|
|
1963
|
-
const
|
|
1967
|
+
const h = this.cobrowseCanvas.getBoundingClientRect(), w = h.width > 0 ? (r.clientX - h.left) / h.width : 0, d = h.height > 0 ? (r.clientY - h.top) / h.height : 0;
|
|
1964
1968
|
return { x: Math.min(1, Math.max(0, w)), y: Math.min(1, Math.max(0, d)) };
|
|
1965
1969
|
}, i = 6e-3;
|
|
1966
1970
|
this.cobrowseCanvas.addEventListener("pointerdown", (r) => {
|
|
@@ -1969,9 +1973,9 @@ Message: ${o.value}`), this.offlinePanel.replaceChildren(c("div", "ocw-offline-t
|
|
|
1969
1973
|
e && (t.push(n(r)), this.redrawCobrowse(), this.drawStroke({ points: t, color: this.cobrowseColor, width: i }));
|
|
1970
1974
|
});
|
|
1971
1975
|
const o = (r) => {
|
|
1972
|
-
var
|
|
1976
|
+
var h, w;
|
|
1973
1977
|
if (e) {
|
|
1974
|
-
e = !1, t.length > 1 && ((w = (
|
|
1978
|
+
e = !1, t.length > 1 && ((w = (h = this.h).onAnnotate) == null || w.call(h, { id: `an_${Date.now()}_${Math.random().toString(36).slice(2)}`, points: t, color: this.cobrowseColor, width: i })), t = [];
|
|
1975
1979
|
try {
|
|
1976
1980
|
this.cobrowseCanvas.releasePointerCapture(r.pointerId);
|
|
1977
1981
|
} catch {
|
|
@@ -1986,8 +1990,8 @@ Message: ${o.value}`), this.offlinePanel.replaceChildren(c("div", "ocw-offline-t
|
|
|
1986
1990
|
if (!i) return;
|
|
1987
1991
|
this.subjectBuilt = !0, this.subjectCard.replaceChildren(), this.subjectCard.append(c("div", "ocw-subject-title", i)), n != null && n.subtitle && this.subjectCard.append(c("div", "ocw-subject-sub", n.subtitle));
|
|
1988
1992
|
const o = c("div", "ocw-tags");
|
|
1989
|
-
if (t) for (const [
|
|
1990
|
-
else for (const
|
|
1993
|
+
if (t) for (const [h, w] of Object.entries(t.fields)) o.append(c("span", "ocw-tag", `${h}: ${w}`));
|
|
1994
|
+
else for (const h of (n == null ? void 0 : n.tags) ?? []) o.append(c("span", "ocw-tag", h));
|
|
1991
1995
|
o.childNodes.length && this.subjectCard.append(o);
|
|
1992
1996
|
const r = (t == null ? void 0 : t.state) ?? (n == null ? void 0 : n.status);
|
|
1993
1997
|
r && (this.statusBadge.textContent = r, this.statusBadge.style.display = "inline-flex");
|
|
@@ -2004,30 +2008,30 @@ Message: ${o.value}`), this.offlinePanel.replaceChildren(c("div", "ocw-offline-t
|
|
|
2004
2008
|
return new Promise((t) => {
|
|
2005
2009
|
const n = c("div", "ocw-modal"), i = c("div", "ocw-modal-card");
|
|
2006
2010
|
i.append(c("div", "ocw-modal-title", e)), i.append(c("div", "ocw-modal-body", `Confirm “${e}”?`));
|
|
2007
|
-
const o = c("div", "ocw-modal-actions"), r = c("button", "ocw-modal-cancel", "Cancel"),
|
|
2011
|
+
const o = c("div", "ocw-modal-actions"), r = c("button", "ocw-modal-cancel", "Cancel"), h = c("button", "ocw-modal-ok", "Confirm"), w = (d) => {
|
|
2008
2012
|
n.remove(), t(d);
|
|
2009
2013
|
};
|
|
2010
|
-
r.addEventListener("click", () => w(!1)),
|
|
2014
|
+
r.addEventListener("click", () => w(!1)), h.addEventListener("click", () => w(!0)), n.addEventListener("click", (d) => {
|
|
2011
2015
|
d.target === n && w(!1);
|
|
2012
|
-
}), o.append(r,
|
|
2016
|
+
}), o.append(r, h), i.append(o), n.append(i), this.root.append(n), h.focus();
|
|
2013
2017
|
});
|
|
2014
2018
|
}
|
|
2015
2019
|
/** Inline form for a form-effect action: typed inputs (date picker, number,
|
|
2016
2020
|
* text) rendered above the composer — no browser prompts. */
|
|
2017
2021
|
openForm(e) {
|
|
2018
|
-
var
|
|
2022
|
+
var h, w;
|
|
2019
2023
|
this.formHost.replaceChildren();
|
|
2020
2024
|
const t = c("div", "ocw-form");
|
|
2021
2025
|
t.append(c("div", "ocw-form-title", e.icon ? `${e.icon} ${e.label}` : e.label));
|
|
2022
2026
|
const n = /* @__PURE__ */ new Map();
|
|
2023
2027
|
for (const d of e.input ?? []) {
|
|
2024
2028
|
const v = c("label", "ocw-form-row");
|
|
2025
|
-
if (v.append(c("span", "ocw-form-lbl", d.label)), d.type === "select" && ((
|
|
2029
|
+
if (v.append(c("span", "ocw-form-lbl", d.label)), d.type === "select" && ((h = d.options) != null && h.length)) {
|
|
2026
2030
|
const x = c("select", "ocw-form-input");
|
|
2027
2031
|
d.required || x.append(c("option", void 0, "— select —"));
|
|
2028
|
-
for (const
|
|
2029
|
-
const
|
|
2030
|
-
|
|
2032
|
+
for (const u of d.options) {
|
|
2033
|
+
const p = c("option");
|
|
2034
|
+
p.value = u, p.textContent = u, x.append(p);
|
|
2031
2035
|
}
|
|
2032
2036
|
d.required && (x.required = !0), v.append(x), n.set(d.name, x);
|
|
2033
2037
|
} else {
|
|
@@ -2052,126 +2056,126 @@ Message: ${o.value}`), this.offlinePanel.replaceChildren(c("div", "ocw-offline-t
|
|
|
2052
2056
|
messageEl(e, t) {
|
|
2053
2057
|
var x;
|
|
2054
2058
|
if (e.senderRole === "system") {
|
|
2055
|
-
const
|
|
2056
|
-
return
|
|
2059
|
+
const u = c("div", "ocw-sys");
|
|
2060
|
+
return u.textContent = e.deletedAt ? "message deleted" : se(e.content), u;
|
|
2057
2061
|
}
|
|
2058
2062
|
const n = e.senderId === this.me, i = !!e.internal, o = c("div", `ocw-row ${i ? "ocw-note mine" : n ? "mine" : "theirs"} ${e.senderRole === "bot" ? "ocw-bot" : ""}`);
|
|
2059
2063
|
!n && !i && o.append(c("div", "ocw-dot", e.senderRole === "bot" ? "🤖" : "🧑"));
|
|
2060
|
-
const r = c("div"),
|
|
2064
|
+
const r = c("div"), h = c("div", "ocw-bubble-wrap");
|
|
2061
2065
|
if (e.replyToId) {
|
|
2062
|
-
const
|
|
2063
|
-
|
|
2066
|
+
const u = c("div", "ocw-reply-to", "↩ replying to a message");
|
|
2067
|
+
u.style.cssText = "font-size:11px;color:var(--ocw-mut);margin-bottom:2px;font-style:italic", r.append(u);
|
|
2064
2068
|
}
|
|
2065
2069
|
const w = c("div", "ocw-bubble");
|
|
2066
2070
|
let d = null;
|
|
2067
2071
|
if (e.deletedAt) w.append(c("span", "ocw-deleted", "message deleted"));
|
|
2068
2072
|
else if (e.content.kind === "attachment") {
|
|
2069
|
-
const
|
|
2070
|
-
if ((x =
|
|
2071
|
-
const
|
|
2072
|
-
|
|
2073
|
+
const u = e.content;
|
|
2074
|
+
if ((x = u.mime) != null && x.startsWith("image/")) {
|
|
2075
|
+
const p = document.createElement("img");
|
|
2076
|
+
p.src = u.url, p.alt = u.name ?? "image", p.style.cssText = "max-width:220px;max-height:160px;border-radius:10px;display:block;cursor:pointer", p.addEventListener("click", () => window.open(u.url, "_blank")), w.append(p);
|
|
2073
2077
|
} else {
|
|
2074
|
-
const
|
|
2075
|
-
|
|
2078
|
+
const p = document.createElement("a");
|
|
2079
|
+
p.href = u.url, p.target = "_blank", p.rel = "noopener", p.style.cssText = "display:flex;align-items:center;gap:8px;color:inherit;text-decoration:none", p.append(c("span", void 0, "📄"), c("span", void 0, u.name ?? "file")), w.append(p);
|
|
2076
2080
|
}
|
|
2077
2081
|
} else if (e.content.kind === "appointment") {
|
|
2078
|
-
const
|
|
2079
|
-
|
|
2082
|
+
const u = e.content, p = c("div", "ocw-appt");
|
|
2083
|
+
p.append(c("div", "ocw-appt-title", `📅 ${u.title}`)), p.append(c("div", "ocw-appt-time", new Date(u.startIso).toLocaleString() + " – " + new Date(u.endIso).toLocaleTimeString())), u.location && p.append(c("div", "ocw-appt-loc", `📍 ${u.location}`)), u.description && p.append(c("div", "ocw-appt-desc", u.description));
|
|
2080
2084
|
const I = c("div", "ocw-appt-links"), m = document.createElement("a");
|
|
2081
|
-
m.href =
|
|
2082
|
-
const
|
|
2083
|
-
|
|
2085
|
+
m.href = u.googleUrl, m.target = "_blank", m.rel = "noopener", m.className = "ocw-appt-btn", m.textContent = "📅 Add to Google Calendar";
|
|
2086
|
+
const y = document.createElement("a");
|
|
2087
|
+
y.href = u.icalUrl, y.download = `${u.title}.ics`, y.className = "ocw-appt-btn ocw-appt-btn-sec", y.textContent = "🍎 Apple / iCal", I.append(m, y), p.append(I), w.append(p);
|
|
2084
2088
|
} else
|
|
2085
2089
|
d = document.createTextNode(se(e.content)), w.append(d), e.editedAt && w.append(c("span", "ocw-edited", "(edited)"));
|
|
2086
|
-
if (
|
|
2087
|
-
const
|
|
2088
|
-
if (
|
|
2089
|
-
const
|
|
2090
|
-
|
|
2090
|
+
if (h.append(w), !n && !i && this.h.onTranslate && e.content.kind === "text" && !e.deletedAt && e.seq > 0 && d) {
|
|
2091
|
+
const u = e.content.text;
|
|
2092
|
+
if (u.trim()) {
|
|
2093
|
+
const p = c("button", "ocw-translate-btn", "🌐");
|
|
2094
|
+
p.type = "button", p.title = "Translate", p.addEventListener("click", (I) => {
|
|
2091
2095
|
if (I.stopPropagation(), this.showingTranslation.has(e.id)) {
|
|
2092
|
-
this.showingTranslation.delete(e.id), d.textContent =
|
|
2096
|
+
this.showingTranslation.delete(e.id), d.textContent = u, p.textContent = "🌐", p.title = "Translate";
|
|
2093
2097
|
return;
|
|
2094
2098
|
}
|
|
2095
2099
|
const m = this.translationCache.get(e.id);
|
|
2096
2100
|
if (m !== void 0) {
|
|
2097
|
-
this.showingTranslation.add(e.id), d.textContent = m,
|
|
2101
|
+
this.showingTranslation.add(e.id), d.textContent = m, p.textContent = "↩", p.title = "Show original";
|
|
2098
2102
|
return;
|
|
2099
2103
|
}
|
|
2100
|
-
|
|
2101
|
-
if (
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
+
p.textContent = "⏳", this.h.onTranslate(u).then((y) => {
|
|
2105
|
+
if (y === null) {
|
|
2106
|
+
p.textContent = "⚠️", p.title = "Translation unavailable", setTimeout(() => {
|
|
2107
|
+
p.textContent = "🌐", p.title = "Translate";
|
|
2104
2108
|
}, 1500);
|
|
2105
2109
|
return;
|
|
2106
2110
|
}
|
|
2107
|
-
this.translationCache.set(e.id,
|
|
2111
|
+
this.translationCache.set(e.id, y), this.showingTranslation.add(e.id), d.textContent = y, p.textContent = "↩", p.title = "Show original";
|
|
2108
2112
|
});
|
|
2109
|
-
}),
|
|
2113
|
+
}), h.append(p);
|
|
2110
2114
|
}
|
|
2111
2115
|
}
|
|
2112
2116
|
if (n && !e.deletedAt && e.seq > 0 && (this.h.onEdit ?? this.h.onDelete)) {
|
|
2113
|
-
const
|
|
2117
|
+
const u = c("div", "ocw-msg-menu");
|
|
2114
2118
|
if (this.h.onEdit) {
|
|
2115
|
-
const
|
|
2116
|
-
|
|
2119
|
+
const p = c("button", void 0, "✏️");
|
|
2120
|
+
p.title = "Edit", p.addEventListener("click", (I) => {
|
|
2117
2121
|
I.stopPropagation();
|
|
2118
|
-
const m = se(e.content),
|
|
2119
|
-
|
|
2122
|
+
const m = se(e.content), y = document.createElement("textarea");
|
|
2123
|
+
y.value = m, y.rows = Math.min(4, Math.ceil(m.length / 40) + 1), y.style.cssText = "width:100%;resize:vertical;border:1px solid var(--ocw-accent);border-radius:8px;padding:6px 10px;font:inherit;font-size:14px;background:#fff;color:#1c1b1a;box-sizing:border-box";
|
|
2120
2124
|
const U = c("button", "ocw-form-submit", "Save");
|
|
2121
2125
|
U.style.cssText = "margin-top:6px;padding:5px 14px;font-size:13px";
|
|
2122
2126
|
const A = c("button", "ocw-form-cancel", "Cancel");
|
|
2123
2127
|
A.style.cssText = "margin-top:6px;padding:5px 10px;font-size:13px";
|
|
2124
|
-
const
|
|
2125
|
-
|
|
2128
|
+
const P = c("div");
|
|
2129
|
+
P.style.cssText = "display:flex;gap:6px;justify-content:flex-end", P.append(A, U);
|
|
2126
2130
|
const K = c("div");
|
|
2127
|
-
K.append(
|
|
2131
|
+
K.append(y, P), w.replaceChildren(K), y.focus(), y.select();
|
|
2128
2132
|
const b = () => w.replaceChildren(d ?? document.createTextNode(m));
|
|
2129
2133
|
A.addEventListener("click", b), U.addEventListener("click", () => {
|
|
2130
|
-
const S =
|
|
2134
|
+
const S = y.value.trim();
|
|
2131
2135
|
S && S !== m && this.h.onEdit(e.id, S), b();
|
|
2132
|
-
}),
|
|
2136
|
+
}), y.addEventListener("keydown", (S) => {
|
|
2133
2137
|
S.key === "Enter" && !S.shiftKey && (S.preventDefault(), U.click()), S.key === "Escape" && b();
|
|
2134
2138
|
});
|
|
2135
|
-
}),
|
|
2139
|
+
}), u.append(p);
|
|
2136
2140
|
}
|
|
2137
2141
|
if (this.h.onDelete) {
|
|
2138
|
-
const
|
|
2139
|
-
|
|
2142
|
+
const p = c("button", "del", "🗑");
|
|
2143
|
+
p.title = "Delete", p.addEventListener("click", (I) => {
|
|
2140
2144
|
I.stopPropagation(), this.h.onDelete(e.id);
|
|
2141
|
-
}),
|
|
2145
|
+
}), u.append(p);
|
|
2142
2146
|
}
|
|
2143
|
-
|
|
2147
|
+
h.append(u);
|
|
2144
2148
|
}
|
|
2145
|
-
if (r.append(
|
|
2146
|
-
const
|
|
2149
|
+
if (r.append(h), this.h.onReact && !e.deletedAt && e.seq > 0) {
|
|
2150
|
+
const u = c("div", "ocw-react-wrap"), p = c("div", "ocw-react");
|
|
2147
2151
|
if (e.reactions && Object.keys(e.reactions).length)
|
|
2148
|
-
for (const [
|
|
2149
|
-
const A = c("button", `ocw-react-pill${U.includes(this.me) ? " mine" : ""}`, `${
|
|
2152
|
+
for (const [y, U] of Object.entries(e.reactions)) {
|
|
2153
|
+
const A = c("button", `ocw-react-pill${U.includes(this.me) ? " mine" : ""}`, `${y} ${U.length}`);
|
|
2150
2154
|
A.addEventListener("click", () => {
|
|
2151
|
-
var
|
|
2152
|
-
return (K = (
|
|
2153
|
-
}),
|
|
2155
|
+
var P, K;
|
|
2156
|
+
return (K = (P = this.h).onReact) == null ? void 0 : K.call(P, e.id, y, U.includes(this.me));
|
|
2157
|
+
}), p.append(A);
|
|
2154
2158
|
}
|
|
2155
2159
|
const I = c("button", "ocw-react-btn", "+"), m = c("div", "ocw-react-picker");
|
|
2156
|
-
for (const
|
|
2157
|
-
const U = c("button", void 0,
|
|
2160
|
+
for (const y of qt) {
|
|
2161
|
+
const U = c("button", void 0, y);
|
|
2158
2162
|
U.addEventListener("click", (A) => {
|
|
2159
2163
|
var K, b, S, M;
|
|
2160
2164
|
A.stopPropagation();
|
|
2161
|
-
const
|
|
2162
|
-
(M = (S = this.h).onReact) == null || M.call(S, e.id,
|
|
2165
|
+
const P = (b = (K = e.reactions) == null ? void 0 : K[y]) == null ? void 0 : b.includes(this.me);
|
|
2166
|
+
(M = (S = this.h).onReact) == null || M.call(S, e.id, y, !!P), m.style.display = "none";
|
|
2163
2167
|
}), m.append(U);
|
|
2164
2168
|
}
|
|
2165
|
-
m.style.display = "none", I.addEventListener("click", (
|
|
2166
|
-
|
|
2169
|
+
m.style.display = "none", I.addEventListener("click", (y) => {
|
|
2170
|
+
y.stopPropagation(), m.style.display = m.style.display === "none" ? "flex" : "none";
|
|
2167
2171
|
}), document.addEventListener("click", () => {
|
|
2168
2172
|
m.style.display = "none";
|
|
2169
|
-
}, { once: !0 }),
|
|
2170
|
-
} else e.reactions && Object.keys(e.reactions).length && r.append(c("div", "ocw-react", Object.entries(e.reactions).map(([
|
|
2173
|
+
}, { once: !0 }), p.append(I), u.append(p, m), r.append(u);
|
|
2174
|
+
} else e.reactions && Object.keys(e.reactions).length && r.append(c("div", "ocw-react", Object.entries(e.reactions).map(([u, p]) => `${u}${p.length}`).join(" ")));
|
|
2171
2175
|
const v = c("div", "ocw-time ocw-meta", Vt(e.ts));
|
|
2172
2176
|
if (n && e.status) {
|
|
2173
|
-
const
|
|
2174
|
-
v.append(
|
|
2177
|
+
const u = c("span", `ocw-tick${e.status === "read" ? " read" : e.status === "delivered" ? " delivered" : ""}`, Xt(e.status));
|
|
2178
|
+
v.append(u);
|
|
2175
2179
|
}
|
|
2176
2180
|
return n && e.seq > 0 && t.lastReadByOthers >= e.seq && v.append(c("span", "ocw-seen", " · Seen")), r.append(v), o.append(r), o;
|
|
2177
2181
|
}
|
|
@@ -2188,29 +2192,29 @@ function Xt(s) {
|
|
|
2188
2192
|
return "🕓";
|
|
2189
2193
|
}
|
|
2190
2194
|
}
|
|
2191
|
-
const
|
|
2192
|
-
function
|
|
2195
|
+
const H = /* @__PURE__ */ new WeakMap(), Z = /* @__PURE__ */ new Map();
|
|
2196
|
+
function ke(s) {
|
|
2193
2197
|
return `relay-launcher::${s.profileId}::${s.subjectId ?? ""}`;
|
|
2194
2198
|
}
|
|
2195
2199
|
function Zt(s) {
|
|
2196
2200
|
var e;
|
|
2197
|
-
(e =
|
|
2201
|
+
(e = H.get(s)) == null || e.close(), H.delete(s);
|
|
2198
2202
|
}
|
|
2199
2203
|
function Qt(s) {
|
|
2200
|
-
var
|
|
2201
|
-
|
|
2202
|
-
const e = $e(), t = s.token ?? s.userId ?? e, n = t !== e ? e : void 0, { wsUrl: i, httpBase: o } =
|
|
2204
|
+
var pe, ue, fe, we, xe;
|
|
2205
|
+
H.has(s.el) && (H.get(s.el).close(), H.delete(s.el)), s.launcher && ((pe = Z.get(ke(s))) == null || pe.close());
|
|
2206
|
+
const e = $e(), t = s.token ?? s.userId ?? e, n = t !== e ? e : void 0, { wsUrl: i, httpBase: o } = He(s.url, s.apiUrl);
|
|
2203
2207
|
let r = new Ct(t);
|
|
2204
|
-
const
|
|
2205
|
-
let d, v = !1, x = null,
|
|
2208
|
+
const h = s.subjectId ? `${t}::${s.subjectId}` : t, w = new At(h);
|
|
2209
|
+
let d, v = !1, x = null, u = null;
|
|
2206
2210
|
!s.launcher && !s.el.style.height && s.el.clientHeight === 0 && (s.el.style.width = s.el.style.width || "100%", s.el.style.height = "600px");
|
|
2207
2211
|
for (const l of w.load()) r.addOptimistic(l.clientMsgId, l.content);
|
|
2208
|
-
let
|
|
2212
|
+
let p = null, I = null, m = 0, y = !s.launcher;
|
|
2209
2213
|
if (s.launcher) {
|
|
2210
|
-
const
|
|
2211
|
-
|
|
2212
|
-
const
|
|
2213
|
-
|
|
2214
|
+
const f = (s.position ?? "bottom-right").includes("right");
|
|
2215
|
+
p = document.createElement("div"), p.style.cssText = `position:fixed;${f ? "right:20px" : "left:20px"};bottom:20px;z-index:9999;display:flex;flex-direction:column;align-items:${f ? "flex-end" : "flex-start"};gap:12px`;
|
|
2216
|
+
const g = document.createElement("div"), E = typeof window < "u" ? window.matchMedia("(max-width: 479px)") : null, X = ($) => {
|
|
2217
|
+
g.style.cssText = $ ? [
|
|
2214
2218
|
"position:fixed",
|
|
2215
2219
|
"inset:0",
|
|
2216
2220
|
"width:100%",
|
|
@@ -2233,66 +2237,66 @@ function Qt(s) {
|
|
|
2233
2237
|
"display:none",
|
|
2234
2238
|
"flex-direction:column",
|
|
2235
2239
|
"background:#fff",
|
|
2236
|
-
"transform-origin:bottom " + (
|
|
2240
|
+
"transform-origin:bottom " + (f ? "right" : "left"),
|
|
2237
2241
|
"transition:opacity .18s,transform .18s",
|
|
2238
2242
|
"opacity:0",
|
|
2239
2243
|
"transform:scale(.95)"
|
|
2240
2244
|
].join(";");
|
|
2241
2245
|
};
|
|
2242
|
-
|
|
2243
|
-
const Y = ($) =>
|
|
2244
|
-
E == null || E.addEventListener("change", Y), x = E,
|
|
2245
|
-
const
|
|
2246
|
-
|
|
2246
|
+
X((E == null ? void 0 : E.matches) ?? !1);
|
|
2247
|
+
const Y = ($) => X($.matches);
|
|
2248
|
+
E == null || E.addEventListener("change", Y), x = E, u = Y, s.el.style.cssText = "width:100%;height:100%;overflow:hidden", g.append(s.el);
|
|
2249
|
+
const B = document.createElement("button");
|
|
2250
|
+
B.style.cssText = [
|
|
2247
2251
|
"width:56px;height:56px;border-radius:50%",
|
|
2248
2252
|
`background:${s.accent ?? "#4F63F5"}`,
|
|
2249
2253
|
"color:#fff;border:none;font-size:24px;cursor:pointer",
|
|
2250
2254
|
"box-shadow:0 4px 16px rgba(0,0,0,.25)",
|
|
2251
2255
|
"position:relative;flex:none",
|
|
2252
2256
|
"transition:transform .15s"
|
|
2253
|
-
].join(";"),
|
|
2254
|
-
|
|
2255
|
-
},
|
|
2256
|
-
|
|
2257
|
-
}, I = document.createElement("span"), I.style.cssText = "position:absolute;top:-4px;right:-4px;background:#ef4444;color:#fff;border-radius:50%;width:20px;height:20px;font-size:11px;font-weight:700;display:none;align-items:center;justify-content:center",
|
|
2257
|
+
].join(";"), B.textContent = "💬", B.onmouseenter = () => {
|
|
2258
|
+
B.style.transform = "scale(1.08)";
|
|
2259
|
+
}, B.onmouseleave = () => {
|
|
2260
|
+
B.style.transform = "scale(1)";
|
|
2261
|
+
}, I = document.createElement("span"), I.style.cssText = "position:absolute;top:-4px;right:-4px;background:#ef4444;color:#fff;border-radius:50%;width:20px;height:20px;font-size:11px;font-weight:700;display:none;align-items:center;justify-content:center", B.append(I), p.append(g, B), document.body.append(p);
|
|
2258
2262
|
const J = ($) => {
|
|
2259
|
-
$ ? (
|
|
2260
|
-
|
|
2261
|
-
})) : (
|
|
2262
|
-
|
|
2263
|
+
$ ? (g.style.display = "flex", requestAnimationFrame(() => {
|
|
2264
|
+
g.style.opacity = "1", g.style.transform = "scale(1)";
|
|
2265
|
+
})) : (g.style.opacity = "0", g.style.transform = "scale(.95)", setTimeout(() => {
|
|
2266
|
+
y || (g.style.display = "none");
|
|
2263
2267
|
}, 180));
|
|
2264
2268
|
};
|
|
2265
|
-
|
|
2266
|
-
|
|
2269
|
+
B.addEventListener("click", () => {
|
|
2270
|
+
y = !y, J(y), B.textContent = y ? "✕" : "💬", B.append(I), y && (m = 0, I && (I.style.display = "none"));
|
|
2267
2271
|
}), document.addEventListener("keydown", ($) => {
|
|
2268
|
-
$.key === "Escape" &&
|
|
2272
|
+
$.key === "Escape" && y && (y = !1, J(!1), B.textContent = "💬", B.append(I));
|
|
2269
2273
|
});
|
|
2270
2274
|
}
|
|
2271
2275
|
const U = () => {
|
|
2272
|
-
|
|
2276
|
+
y || (m++, I && (I.textContent = String(m), I.style.display = "flex"));
|
|
2273
2277
|
}, A = () => {
|
|
2274
2278
|
try {
|
|
2275
|
-
const l = new AudioContext(),
|
|
2276
|
-
|
|
2279
|
+
const l = new AudioContext(), f = l.createOscillator(), g = l.createGain();
|
|
2280
|
+
f.connect(g), g.connect(l.destination), f.frequency.setValueAtTime(880, l.currentTime), f.frequency.exponentialRampToValueAtTime(440, l.currentTime + 0.15), g.gain.setValueAtTime(0.3, l.currentTime), g.gain.exponentialRampToValueAtTime(1e-3, l.currentTime + 0.3), f.start(), f.stop(l.currentTime + 0.3);
|
|
2277
2281
|
} catch {
|
|
2278
2282
|
}
|
|
2279
|
-
},
|
|
2280
|
-
for (;
|
|
2281
|
-
const
|
|
2282
|
-
w.add({ clientMsgId:
|
|
2283
|
+
}, P = [], K = (l) => {
|
|
2284
|
+
for (; P.length; ) {
|
|
2285
|
+
const f = P.shift();
|
|
2286
|
+
w.add({ clientMsgId: f.clientMsgId, content: f.content, ts: Date.now() }), b.send({ type: "send", conversationId: l, clientMsgId: f.clientMsgId, content: f.content });
|
|
2283
2287
|
}
|
|
2284
2288
|
};
|
|
2285
2289
|
let b;
|
|
2286
2290
|
const S = new Ft(`ocw-e2e-${s.profileId}`);
|
|
2287
2291
|
let M = !1;
|
|
2288
2292
|
const k = [], T = [];
|
|
2289
|
-
let
|
|
2290
|
-
const ne = (l,
|
|
2291
|
-
S.sealText(
|
|
2292
|
-
d && b.send({ type: "send", conversationId: d, clientMsgId: l, content:
|
|
2293
|
+
let V = !1;
|
|
2294
|
+
const ne = (l, f) => {
|
|
2295
|
+
S.sealText(f).then((g) => {
|
|
2296
|
+
d && b.send({ type: "send", conversationId: d, clientMsgId: l, content: g });
|
|
2293
2297
|
});
|
|
2294
|
-
},
|
|
2295
|
-
S.sealText(
|
|
2298
|
+
}, Pe = (l, f, g) => {
|
|
2299
|
+
S.sealText(f, g).then((E) => {
|
|
2296
2300
|
d && b.send({ type: "send", conversationId: d, clientMsgId: l, content: E });
|
|
2297
2301
|
});
|
|
2298
2302
|
}, Be = () => {
|
|
@@ -2304,37 +2308,37 @@ function Qt(s) {
|
|
|
2304
2308
|
const l = T.shift();
|
|
2305
2309
|
ne(l.clientMsgId, l.text);
|
|
2306
2310
|
}
|
|
2307
|
-
},
|
|
2311
|
+
}, Ae = (l) => {
|
|
2308
2312
|
b.send({ type: "fetchPrekey", targetUserId: l });
|
|
2309
|
-
},
|
|
2310
|
-
|
|
2313
|
+
}, Ke = s.i18n ?? {}, ze = ["ar", "he", "fa", "ur"], Le = typeof navigator < "u" ? (navigator.language ?? "").slice(0, 2).toLowerCase() : "";
|
|
2314
|
+
ze.includes(Le) && !s.el.dir && (s.el.dir = "rtl", s.el.style.fontFamily = s.el.style.fontFamily || "Tahoma,Arial,system-ui,sans-serif");
|
|
2311
2315
|
const L = new Wt(s.el, t, {
|
|
2312
2316
|
onSend(l) {
|
|
2313
|
-
const
|
|
2314
|
-
r.addOptimistic(
|
|
2317
|
+
const f = `cm_${Math.random().toString(36).slice(2)}`, g = { kind: "text", text: l };
|
|
2318
|
+
r.addOptimistic(f, g), L.render(r), r.e2e ? S.ready ? ne(f, l) : V ? T.push({ clientMsgId: f, text: l }) : (k.push({ clientMsgId: f, text: l }), r.assignedAgentId && Ae(r.assignedAgentId)) : d ? (w.add({ clientMsgId: f, content: g, ts: Date.now() }), b.send({ type: "send", conversationId: d, clientMsgId: f, content: g })) : P.push({ clientMsgId: f, content: g });
|
|
2315
2319
|
},
|
|
2316
2320
|
async onAttach(l) {
|
|
2317
2321
|
if (!d) return;
|
|
2318
|
-
const
|
|
2319
|
-
r.addOptimistic(
|
|
2322
|
+
const f = `${o}/upload?name=${encodeURIComponent(l.name)}`, g = `cm_${Math.random().toString(36).slice(2)}`;
|
|
2323
|
+
r.addOptimistic(g, { kind: "text", text: `📎 Uploading ${l.name}…` }), L.render(r);
|
|
2320
2324
|
try {
|
|
2321
|
-
const E = await fetch(
|
|
2325
|
+
const E = await fetch(f, {
|
|
2322
2326
|
method: "POST",
|
|
2323
2327
|
headers: { "content-type": l.type, ...s.token ? { authorization: `Bearer ${s.token}` } : {} },
|
|
2324
2328
|
body: l
|
|
2325
2329
|
});
|
|
2326
2330
|
if (!E.ok) throw new Error(`Upload failed: ${E.status}`);
|
|
2327
|
-
const { url:
|
|
2328
|
-
b.send({ type: "send", conversationId: d, clientMsgId:
|
|
2331
|
+
const { url: X, name: Y, mime: B, size: J } = await E.json();
|
|
2332
|
+
b.send({ type: "send", conversationId: d, clientMsgId: g, content: { kind: "attachment", url: X, name: Y, mime: B, size: J } });
|
|
2329
2333
|
} catch (E) {
|
|
2330
|
-
r.addOptimistic(
|
|
2334
|
+
r.addOptimistic(g, { kind: "text", text: `⚠️ Upload failed: ${E.message}` }), L.render(r);
|
|
2331
2335
|
}
|
|
2332
2336
|
},
|
|
2333
|
-
onInvoke(l,
|
|
2334
|
-
d && b.send({ type: "invoke", conversationId: d, actionId: l, clientInvokeId: `iv_${Math.random().toString(36).slice(2)}`, ...
|
|
2337
|
+
onInvoke(l, f) {
|
|
2338
|
+
d && b.send({ type: "invoke", conversationId: d, actionId: l, clientInvokeId: `iv_${Math.random().toString(36).slice(2)}`, ...f ? { inputs: f } : {} });
|
|
2335
2339
|
},
|
|
2336
|
-
onTyping(l,
|
|
2337
|
-
d && b.send({ type: "typing", conversationId: d, isTyping: l, ...
|
|
2340
|
+
onTyping(l, f) {
|
|
2341
|
+
d && b.send({ type: "typing", conversationId: d, isTyping: l, ...f ? { preview: f } : {} });
|
|
2338
2342
|
},
|
|
2339
2343
|
onReadUpTo(l) {
|
|
2340
2344
|
d && b.send({ type: "read", conversationId: d, seq: l });
|
|
@@ -2344,14 +2348,14 @@ function Qt(s) {
|
|
|
2344
2348
|
const l = r.messages()[0];
|
|
2345
2349
|
l && b.send({ type: "history", conversationId: d, beforeSeq: l.seq, limit: 20 });
|
|
2346
2350
|
},
|
|
2347
|
-
onEdit(l,
|
|
2348
|
-
d && b.send({ type: "edit", conversationId: d, messageId: l, content: { kind: "text", text:
|
|
2351
|
+
onEdit(l, f) {
|
|
2352
|
+
d && b.send({ type: "edit", conversationId: d, messageId: l, content: { kind: "text", text: f } });
|
|
2349
2353
|
},
|
|
2350
2354
|
onDelete(l) {
|
|
2351
2355
|
d && b.send({ type: "delete", conversationId: d, messageId: l });
|
|
2352
2356
|
},
|
|
2353
|
-
onReact(l,
|
|
2354
|
-
d && b.send({ type: "react", conversationId: d, messageId: l, emoji:
|
|
2357
|
+
onReact(l, f, g) {
|
|
2358
|
+
d && b.send({ type: "react", conversationId: d, messageId: l, emoji: f, remove: g });
|
|
2355
2359
|
},
|
|
2356
2360
|
onCsat(l) {
|
|
2357
2361
|
d && fetch(`${o}/conversations/${d}/csat`, {
|
|
@@ -2370,14 +2374,14 @@ function Qt(s) {
|
|
|
2370
2374
|
...s.translateLang ? {
|
|
2371
2375
|
async onTranslate(l) {
|
|
2372
2376
|
try {
|
|
2373
|
-
const
|
|
2377
|
+
const f = await fetch(`${o}/translate`, {
|
|
2374
2378
|
method: "POST",
|
|
2375
2379
|
headers: { "content-type": "application/json", authorization: `Bearer ${t}` },
|
|
2376
2380
|
body: JSON.stringify({ text: l, targetLang: s.translateLang })
|
|
2377
2381
|
});
|
|
2378
|
-
if (!
|
|
2379
|
-
const { translated:
|
|
2380
|
-
return
|
|
2382
|
+
if (!f.ok) return null;
|
|
2383
|
+
const { translated: g } = await f.json();
|
|
2384
|
+
return g;
|
|
2381
2385
|
} catch {
|
|
2382
2386
|
return null;
|
|
2383
2387
|
}
|
|
@@ -2387,56 +2391,53 @@ function Qt(s) {
|
|
|
2387
2391
|
...s.subject ? { subject: s.subject } : {},
|
|
2388
2392
|
...s.quickReplies ? { quickReplies: s.quickReplies } : {},
|
|
2389
2393
|
...s.accent ? { accent: s.accent } : {},
|
|
2390
|
-
...(
|
|
2391
|
-
i18n:
|
|
2392
|
-
}),
|
|
2394
|
+
...(ue = s.user) != null && ue.name || (fe = s.user) != null && fe.avatar ? { userInfo: { ...s.user.name ? { name: s.user.name } : {}, ...s.user.avatar ? { avatar: s.user.avatar } : {} } } : {},
|
|
2395
|
+
i18n: Ke
|
|
2396
|
+
}), he = s.user && (s.user.name || s.user.email || s.user.avatar || s.user.meta) ? {
|
|
2397
|
+
...s.user.name ? { name: s.user.name } : {},
|
|
2398
|
+
...s.user.email ? { email: s.user.email } : {},
|
|
2399
|
+
...s.user.avatar ? { avatar: s.user.avatar } : {},
|
|
2400
|
+
...s.user.meta ? { meta: s.user.meta } : {}
|
|
2401
|
+
} : void 0, Me = {
|
|
2393
2402
|
type: "open",
|
|
2394
2403
|
profileId: s.profileId,
|
|
2395
2404
|
...s.subjectId ? { subjectId: s.subjectId } : {},
|
|
2396
2405
|
...n ? { linkFrom: n } : {},
|
|
2406
|
+
...he ? { userInfo: he } : {},
|
|
2397
2407
|
...typeof location < "u" ? { pageUrl: location.href } : {},
|
|
2398
2408
|
...typeof document < "u" && document.title ? { pageTitle: document.title } : {},
|
|
2399
2409
|
// Pass subject display info so the server can persist it to the Subject record.
|
|
2400
2410
|
// This is how listingTitle and listingMeta get saved without a separate API call.
|
|
2401
|
-
...(
|
|
2402
|
-
...(
|
|
2403
|
-
}, Me = (l) => {
|
|
2404
|
-
const h = s.user;
|
|
2405
|
-
if (!h || !h.name && !h.email && !h.avatar && !h.meta) return;
|
|
2406
|
-
const y = [];
|
|
2407
|
-
if (h.name && y.push(`Name: ${h.name}`), h.email && y.push(`Email: ${h.email}`), h.avatar && y.push(`Avatar: ${h.avatar}`), h.meta) for (const [E, H] of Object.entries(h.meta)) y.push(`${E}: ${H}`);
|
|
2408
|
-
b.send({ type: "note", conversationId: l, clientMsgId: `ui_${Date.now()}`, text: `[User info]
|
|
2409
|
-
${y.join(`
|
|
2410
|
-
`)}` });
|
|
2411
|
+
...(we = s.subject) != null && we.title ? { subjectTitle: s.subject.title } : {},
|
|
2412
|
+
...(xe = s.subject) != null && xe.subtitle ? { subjectMeta: s.subject.subtitle } : {}
|
|
2411
2413
|
};
|
|
2412
2414
|
b = new Et({
|
|
2413
2415
|
url: i,
|
|
2414
2416
|
token: t,
|
|
2415
|
-
open:
|
|
2417
|
+
open: Me,
|
|
2416
2418
|
getCursor: () => r.highestSeq(),
|
|
2417
|
-
onStatusChange: (l,
|
|
2419
|
+
onStatusChange: (l, f) => L.setConnStatus(l, f),
|
|
2418
2420
|
onFrame(l) {
|
|
2419
2421
|
if (l.type === "opened") {
|
|
2420
|
-
const h = d === void 0;
|
|
2421
2422
|
if (d = l.conversation.id, !v) {
|
|
2422
2423
|
v = !0;
|
|
2423
|
-
for (const
|
|
2424
|
-
b.send({ type: "send", conversationId: d, clientMsgId:
|
|
2424
|
+
for (const f of w.load())
|
|
2425
|
+
b.send({ type: "send", conversationId: d, clientMsgId: f.clientMsgId, content: f.content });
|
|
2425
2426
|
}
|
|
2426
|
-
|
|
2427
|
+
Re(i, t, d, r, L, o), P.length && K(d);
|
|
2427
2428
|
}
|
|
2428
2429
|
if (l.type === "ack" && w.remove(l.clientMsgId), l.type === "prekeyBundle") {
|
|
2429
|
-
l.bundle && (
|
|
2430
|
-
const
|
|
2431
|
-
for (const E of
|
|
2430
|
+
l.bundle && (V = !0, S.x3dhSendTo(l.bundle).then((f) => {
|
|
2431
|
+
const g = [...k.splice(0), ...T.splice(0)];
|
|
2432
|
+
for (const E of g) Pe(E.clientMsgId, E.text, f);
|
|
2432
2433
|
L.render(r);
|
|
2433
2434
|
}));
|
|
2434
2435
|
return;
|
|
2435
2436
|
}
|
|
2436
2437
|
if (l.type === "message" && r.e2e) {
|
|
2437
|
-
const
|
|
2438
|
-
if (
|
|
2439
|
-
S.x3dhReceiveFrom(
|
|
2438
|
+
const f = jt(l.message.content);
|
|
2439
|
+
if (f && !S.ready) {
|
|
2440
|
+
S.x3dhReceiveFrom(f.x3dhIK, f.x3dhEK, f.x3dhSPK).then(async () => {
|
|
2440
2441
|
await S.openFrame(l), r.apply(l), L.render(r);
|
|
2441
2442
|
});
|
|
2442
2443
|
return;
|
|
@@ -2451,19 +2452,19 @@ ${y.join(`
|
|
|
2451
2452
|
(async () => {
|
|
2452
2453
|
if (r.e2e && await S.openFrame(l), r.apply(l), l.type === "message" && l.message.senderId !== t && !l.message.internal && (U(), A()), r.e2e && d && !M) {
|
|
2453
2454
|
M = !0;
|
|
2454
|
-
const
|
|
2455
|
-
b.send({ type: "uploadPrekeys", ...
|
|
2456
|
-
const
|
|
2457
|
-
b.send({ type: "pubkey", conversationId: d, key:
|
|
2455
|
+
const f = await S.initX3DH();
|
|
2456
|
+
b.send({ type: "uploadPrekeys", ...f });
|
|
2457
|
+
const g = await S.begin();
|
|
2458
|
+
b.send({ type: "pubkey", conversationId: d, key: g });
|
|
2458
2459
|
}
|
|
2459
2460
|
L.render(r);
|
|
2460
2461
|
})();
|
|
2461
2462
|
}
|
|
2462
2463
|
}), b.connect(), L.render(r);
|
|
2463
|
-
const
|
|
2464
|
-
b.close(),
|
|
2464
|
+
const F = s.launcher ? ke(s) : null, W = { close: () => {
|
|
2465
|
+
b.close(), p == null || p.remove(), L.destroy(), x && u && x.removeEventListener("change", u), H.delete(s.el), F && Z.get(F) === W && Z.delete(F);
|
|
2465
2466
|
} };
|
|
2466
|
-
return
|
|
2467
|
+
return H.set(s.el, W), F && Z.set(F, W), W;
|
|
2467
2468
|
}
|
|
2468
2469
|
export {
|
|
2469
2470
|
Ct as ChatStore,
|
|
@@ -2475,8 +2476,8 @@ export {
|
|
|
2475
2476
|
jt as extractX3DHInit,
|
|
2476
2477
|
nn as httpBaseFromWsUrl,
|
|
2477
2478
|
Qt as mount,
|
|
2478
|
-
|
|
2479
|
-
|
|
2479
|
+
He as resolveRelayUrls,
|
|
2480
|
+
Re as restoreHistory,
|
|
2480
2481
|
Zt as unmount
|
|
2481
2482
|
};
|
|
2482
2483
|
//# sourceMappingURL=index.js.map
|