@paramms/chat-widget 1.0.0 → 1.0.1
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/index.js +359 -318
- package/dist/index.js.map +1 -1
- package/dist/react.d.ts +20 -5
- package/dist/react.js +6 -0
- package/dist/react.js.map +1 -1
- package/dist/renderer.d.ts +4 -0
- package/package.json +10 -4
package/dist/index.js
CHANGED
|
@@ -63,14 +63,14 @@ function pe(s, e, t) {
|
|
|
63
63
|
if (!(d & 128))
|
|
64
64
|
o.push(d);
|
|
65
65
|
else if ((d & 224) === 192) {
|
|
66
|
-
const
|
|
67
|
-
o.push((d & 31) << 6 |
|
|
66
|
+
const u = s[n++] & 63;
|
|
67
|
+
o.push((d & 31) << 6 | u);
|
|
68
68
|
} else if ((d & 240) === 224) {
|
|
69
|
-
const
|
|
70
|
-
o.push((d & 31) << 12 |
|
|
69
|
+
const u = s[n++] & 63, w = s[n++] & 63;
|
|
70
|
+
o.push((d & 31) << 12 | u << 6 | w);
|
|
71
71
|
} else if ((d & 248) === 240) {
|
|
72
|
-
const
|
|
73
|
-
let x = (d & 7) << 18 |
|
|
72
|
+
const u = s[n++] & 63, w = s[n++] & 63, y = s[n++] & 63;
|
|
73
|
+
let x = (d & 7) << 18 | u << 12 | w << 6 | y;
|
|
74
74
|
x > 65535 && (x -= 65536, o.push(x >>> 10 & 1023 | 55296), x = 56320 | x & 1023), o.push(x);
|
|
75
75
|
} else
|
|
76
76
|
o.push(d);
|
|
@@ -104,16 +104,16 @@ class U extends Error {
|
|
|
104
104
|
});
|
|
105
105
|
}
|
|
106
106
|
}
|
|
107
|
-
const
|
|
107
|
+
const F = 4294967295;
|
|
108
108
|
function $e(s, e, t) {
|
|
109
109
|
const n = t / 4294967296, i = t;
|
|
110
110
|
s.setUint32(e, n), s.setUint32(e + 4, i);
|
|
111
111
|
}
|
|
112
|
-
function
|
|
112
|
+
function fe(s, e, t) {
|
|
113
113
|
const n = Math.floor(t / 4294967296), i = t;
|
|
114
114
|
s.setUint32(e, n), s.setUint32(e + 4, i);
|
|
115
115
|
}
|
|
116
|
-
function
|
|
116
|
+
function ue(s, e) {
|
|
117
117
|
const t = s.getInt32(e), n = s.getUint32(e + 4);
|
|
118
118
|
return t * 4294967296 + n;
|
|
119
119
|
}
|
|
@@ -133,7 +133,7 @@ function He({ sec: s, nsec: e }) {
|
|
|
133
133
|
}
|
|
134
134
|
else {
|
|
135
135
|
const t = new Uint8Array(12), n = new DataView(t.buffer);
|
|
136
|
-
return n.setUint32(0, e),
|
|
136
|
+
return n.setUint32(0, e), fe(n, 4, s), t;
|
|
137
137
|
}
|
|
138
138
|
}
|
|
139
139
|
function Fe(s) {
|
|
@@ -160,7 +160,7 @@ function Oe(s) {
|
|
|
160
160
|
return { sec: i, nsec: o };
|
|
161
161
|
}
|
|
162
162
|
case 12: {
|
|
163
|
-
const t =
|
|
163
|
+
const t = ue(e, 4), n = e.getUint32(0);
|
|
164
164
|
return { sec: t, nsec: n };
|
|
165
165
|
}
|
|
166
166
|
default:
|
|
@@ -460,7 +460,7 @@ class ne {
|
|
|
460
460
|
this.ensureBufferSizeToWrite(8), $e(this.view, this.pos, e), this.pos += 8;
|
|
461
461
|
}
|
|
462
462
|
writeI64(e) {
|
|
463
|
-
this.ensureBufferSizeToWrite(8),
|
|
463
|
+
this.ensureBufferSizeToWrite(8), fe(this.view, this.pos, e), this.pos += 8;
|
|
464
464
|
}
|
|
465
465
|
writeBigUint64(e) {
|
|
466
466
|
this.ensureBufferSizeToWrite(8), this.view.setBigUint64(this.pos, e), this.pos += 8;
|
|
@@ -514,7 +514,7 @@ class Qe {
|
|
|
514
514
|
return this.store(r, o), o;
|
|
515
515
|
}
|
|
516
516
|
}
|
|
517
|
-
const te = "array",
|
|
517
|
+
const te = "array", O = "map_key", we = "map_value", et = (s) => {
|
|
518
518
|
if (typeof s == "string" || typeof s == "number")
|
|
519
519
|
return s;
|
|
520
520
|
throw new U("The type of key must be string or number but " + typeof s);
|
|
@@ -536,7 +536,7 @@ class tt {
|
|
|
536
536
|
}
|
|
537
537
|
pushMapState(e) {
|
|
538
538
|
const t = this.getUninitializedStateFromPool();
|
|
539
|
-
t.type =
|
|
539
|
+
t.type = O, t.readCount = 0, t.size = e, t.map = {};
|
|
540
540
|
}
|
|
541
541
|
getUninitializedStateFromPool() {
|
|
542
542
|
if (this.stackHeadPosition++, this.stackHeadPosition === this.stack.length) {
|
|
@@ -560,7 +560,7 @@ class tt {
|
|
|
560
560
|
const n = e;
|
|
561
561
|
n.size = 0, n.array = void 0, n.position = 0, n.type = void 0;
|
|
562
562
|
}
|
|
563
|
-
if (e.type ===
|
|
563
|
+
if (e.type === O || e.type === we) {
|
|
564
564
|
const n = e;
|
|
565
565
|
n.size = 0, n.map = void 0, n.readCount = 0, n.type = void 0;
|
|
566
566
|
}
|
|
@@ -570,7 +570,7 @@ class tt {
|
|
|
570
570
|
this.stack.length = 0, this.stackHeadPosition = -1;
|
|
571
571
|
}
|
|
572
572
|
}
|
|
573
|
-
const
|
|
573
|
+
const j = -1, se = new DataView(new ArrayBuffer(0)), it = new Uint8Array(se.buffer);
|
|
574
574
|
try {
|
|
575
575
|
se.getInt8(0);
|
|
576
576
|
} catch (s) {
|
|
@@ -595,10 +595,10 @@ class oe {
|
|
|
595
595
|
a(this, "pos", 0);
|
|
596
596
|
a(this, "view", se);
|
|
597
597
|
a(this, "bytes", it);
|
|
598
|
-
a(this, "headByte",
|
|
598
|
+
a(this, "headByte", j);
|
|
599
599
|
a(this, "stack", new tt());
|
|
600
600
|
a(this, "entered", !1);
|
|
601
|
-
this.extensionCodec = (e == null ? void 0 : e.extensionCodec) ?? Y.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) ??
|
|
601
|
+
this.extensionCodec = (e == null ? void 0 : e.extensionCodec) ?? Y.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) ?? F, this.maxBinLength = (e == null ? void 0 : e.maxBinLength) ?? F, this.maxArrayLength = (e == null ? void 0 : e.maxArrayLength) ?? F, this.maxMapLength = (e == null ? void 0 : e.maxMapLength) ?? F, this.maxExtLength = (e == null ? void 0 : e.maxExtLength) ?? F, this.keyDecoder = (e == null ? void 0 : e.keyDecoder) !== void 0 ? e.keyDecoder : nt, this.mapKeyConverter = (e == null ? void 0 : e.mapKeyConverter) ?? et;
|
|
602
602
|
}
|
|
603
603
|
clone() {
|
|
604
604
|
return new oe({
|
|
@@ -615,14 +615,14 @@ class oe {
|
|
|
615
615
|
});
|
|
616
616
|
}
|
|
617
617
|
reinitializeState() {
|
|
618
|
-
this.totalPos = 0, this.headByte =
|
|
618
|
+
this.totalPos = 0, this.headByte = j, this.stack.reset();
|
|
619
619
|
}
|
|
620
620
|
setBuffer(e) {
|
|
621
621
|
const t = ee(e);
|
|
622
622
|
this.bytes = t, this.view = new DataView(t.buffer, t.byteOffset, t.byteLength), this.pos = 0;
|
|
623
623
|
}
|
|
624
624
|
appendBuffer(e) {
|
|
625
|
-
if (this.headByte ===
|
|
625
|
+
if (this.headByte === j && !this.hasRemaining(1))
|
|
626
626
|
this.setBuffer(e);
|
|
627
627
|
else {
|
|
628
628
|
const t = this.bytes.subarray(this.pos), n = ee(e), i = new Uint8Array(t.length + n.length);
|
|
@@ -677,9 +677,9 @@ class oe {
|
|
|
677
677
|
this.appendBuffer(d);
|
|
678
678
|
try {
|
|
679
679
|
n = this.doDecodeSync(), t = !0;
|
|
680
|
-
} catch (
|
|
681
|
-
if (!(
|
|
682
|
-
throw
|
|
680
|
+
} catch (u) {
|
|
681
|
+
if (!(u instanceof RangeError))
|
|
682
|
+
throw u;
|
|
683
683
|
}
|
|
684
684
|
this.totalPos += this.pos;
|
|
685
685
|
}
|
|
@@ -854,7 +854,7 @@ class oe {
|
|
|
854
854
|
t = i.array, n.release(i);
|
|
855
855
|
else
|
|
856
856
|
continue e;
|
|
857
|
-
else if (i.type ===
|
|
857
|
+
else if (i.type === O) {
|
|
858
858
|
if (t === "__proto__")
|
|
859
859
|
throw new U("The key __proto__ is not allowed");
|
|
860
860
|
i.key = this.mapKeyConverter(t), i.type = we;
|
|
@@ -862,7 +862,7 @@ class oe {
|
|
|
862
862
|
} else if (i.map[i.key] = t, i.readCount++, i.readCount === i.size)
|
|
863
863
|
t = i.map, n.release(i);
|
|
864
864
|
else {
|
|
865
|
-
i.key = null, i.type =
|
|
865
|
+
i.key = null, i.type = O;
|
|
866
866
|
continue e;
|
|
867
867
|
}
|
|
868
868
|
}
|
|
@@ -870,10 +870,10 @@ class oe {
|
|
|
870
870
|
}
|
|
871
871
|
}
|
|
872
872
|
readHeadByte() {
|
|
873
|
-
return this.headByte ===
|
|
873
|
+
return this.headByte === j && (this.headByte = this.readU8()), this.headByte;
|
|
874
874
|
}
|
|
875
875
|
complete() {
|
|
876
|
-
this.headByte =
|
|
876
|
+
this.headByte = j;
|
|
877
877
|
}
|
|
878
878
|
readArraySize() {
|
|
879
879
|
const e = this.readHeadByte();
|
|
@@ -916,7 +916,7 @@ class oe {
|
|
|
916
916
|
return this.stateIsMapKey() && ((o = this.keyDecoder) != null && o.canBeCached(e)) ? i = this.keyDecoder.decode(this.bytes, n, e) : i = Me(this.bytes, n, e), this.pos += t + e, i;
|
|
917
917
|
}
|
|
918
918
|
stateIsMapKey() {
|
|
919
|
-
return this.stack.length > 0 ? this.stack.top().type ===
|
|
919
|
+
return this.stack.length > 0 ? this.stack.top().type === O : !1;
|
|
920
920
|
}
|
|
921
921
|
/**
|
|
922
922
|
* @throws {@link RangeError}
|
|
@@ -977,7 +977,7 @@ class oe {
|
|
|
977
977
|
return this.pos += 8, e;
|
|
978
978
|
}
|
|
979
979
|
readI64() {
|
|
980
|
-
const e =
|
|
980
|
+
const e = ue(this.view, this.pos);
|
|
981
981
|
return this.pos += 8, e;
|
|
982
982
|
}
|
|
983
983
|
readU64AsBigInt() {
|
|
@@ -1271,7 +1271,7 @@ function ht(s) {
|
|
|
1271
1271
|
return new WebSocket(s);
|
|
1272
1272
|
}
|
|
1273
1273
|
const ce = 200, pt = 7 * 864e5;
|
|
1274
|
-
class
|
|
1274
|
+
class ft {
|
|
1275
1275
|
constructor(e) {
|
|
1276
1276
|
a(this, "key");
|
|
1277
1277
|
this.key = `ocw_outbox_${e}`;
|
|
@@ -1309,7 +1309,7 @@ class ut {
|
|
|
1309
1309
|
}
|
|
1310
1310
|
}
|
|
1311
1311
|
}
|
|
1312
|
-
const
|
|
1312
|
+
const I = () => globalThis.crypto.subtle;
|
|
1313
1313
|
function J(s) {
|
|
1314
1314
|
const e = s instanceof Uint8Array ? s : new Uint8Array(s);
|
|
1315
1315
|
let t = "";
|
|
@@ -1321,19 +1321,19 @@ function ie(s) {
|
|
|
1321
1321
|
for (let i = 0; i < e.length; i++) n[i] = e.charCodeAt(i);
|
|
1322
1322
|
return n;
|
|
1323
1323
|
}
|
|
1324
|
-
async function
|
|
1325
|
-
const s = await
|
|
1324
|
+
async function N() {
|
|
1325
|
+
const s = await I().generateKey({ name: "ECDH", namedCurve: "P-256" }, !0, ["deriveKey", "deriveBits"]);
|
|
1326
1326
|
return { publicKey: s.publicKey, privateKey: s.privateKey };
|
|
1327
1327
|
}
|
|
1328
|
-
async function
|
|
1329
|
-
return J(await
|
|
1328
|
+
async function M(s) {
|
|
1329
|
+
return J(await I().exportKey("raw", s));
|
|
1330
1330
|
}
|
|
1331
|
-
async function
|
|
1332
|
-
return
|
|
1331
|
+
async function H(s) {
|
|
1332
|
+
return I().importKey("raw", ie(s), { name: "ECDH", namedCurve: "P-256" }, !1, []);
|
|
1333
1333
|
}
|
|
1334
|
-
async function
|
|
1335
|
-
const t = await
|
|
1336
|
-
return
|
|
1334
|
+
async function ut(s, e) {
|
|
1335
|
+
const t = await H(e);
|
|
1336
|
+
return I().deriveKey(
|
|
1337
1337
|
{ name: "ECDH", public: t },
|
|
1338
1338
|
s,
|
|
1339
1339
|
{ name: "AES-GCM", length: 256 },
|
|
@@ -1342,11 +1342,11 @@ async function ft(s, e) {
|
|
|
1342
1342
|
);
|
|
1343
1343
|
}
|
|
1344
1344
|
async function wt(s, e) {
|
|
1345
|
-
const t = globalThis.crypto.getRandomValues(new Uint8Array(12)), n = new TextEncoder().encode(e), i = await
|
|
1345
|
+
const t = globalThis.crypto.getRandomValues(new Uint8Array(12)), n = new TextEncoder().encode(e), i = await I().encrypt({ name: "AES-GCM", iv: t }, s, n);
|
|
1346
1346
|
return { ct: J(i), iv: J(t) };
|
|
1347
1347
|
}
|
|
1348
1348
|
async function xt(s, e, t) {
|
|
1349
|
-
const n = await
|
|
1349
|
+
const n = await I().decrypt({ name: "AES-GCM", iv: ie(t) }, s, ie(e));
|
|
1350
1350
|
return new TextDecoder().decode(n);
|
|
1351
1351
|
}
|
|
1352
1352
|
async function gt(s) {
|
|
@@ -1354,30 +1354,30 @@ async function gt(s) {
|
|
|
1354
1354
|
try {
|
|
1355
1355
|
const i = (t = globalThis.localStorage) == null ? void 0 : t.getItem(s);
|
|
1356
1356
|
if (i) {
|
|
1357
|
-
const { pub: o, priv: r } = JSON.parse(i), d = await
|
|
1358
|
-
return { publicKey: d, privateKey:
|
|
1357
|
+
const { pub: o, priv: r } = JSON.parse(i), d = await I().importKey("jwk", o, { name: "ECDH", namedCurve: "P-256" }, !0, []), u = await I().importKey("jwk", r, { name: "ECDH", namedCurve: "P-256" }, !0, ["deriveKey", "deriveBits"]);
|
|
1358
|
+
return { publicKey: d, privateKey: u };
|
|
1359
1359
|
}
|
|
1360
1360
|
} catch {
|
|
1361
1361
|
}
|
|
1362
|
-
const e = await
|
|
1362
|
+
const e = await N();
|
|
1363
1363
|
try {
|
|
1364
|
-
const i = await
|
|
1364
|
+
const i = await I().exportKey("jwk", e.publicKey), o = await I().exportKey("jwk", e.privateKey);
|
|
1365
1365
|
(n = globalThis.localStorage) == null || n.setItem(s, JSON.stringify({ pub: i, priv: o }));
|
|
1366
1366
|
} catch {
|
|
1367
1367
|
}
|
|
1368
1368
|
return e;
|
|
1369
1369
|
}
|
|
1370
1370
|
async function yt(s, e) {
|
|
1371
|
-
const t = await
|
|
1371
|
+
const t = await I().exportKey("raw", e), n = await I().sign({ name: "ECDSA", hash: "SHA-256" }, s, t);
|
|
1372
1372
|
return J(n);
|
|
1373
1373
|
}
|
|
1374
1374
|
async function bt() {
|
|
1375
|
-
const s = await
|
|
1375
|
+
const s = await N(), e = await I().generateKey({ name: "ECDSA", namedCurve: "P-256" }, !0, ["sign", "verify"]);
|
|
1376
1376
|
return {
|
|
1377
1377
|
ecdhKP: s,
|
|
1378
1378
|
ecdsaKP: { publicKey: e.publicKey, privateKey: e.privateKey },
|
|
1379
|
-
publicKeyB64: await
|
|
1380
|
-
sigPublicKeyB64: await
|
|
1379
|
+
publicKeyB64: await M(s.publicKey),
|
|
1380
|
+
sigPublicKeyB64: await M(e.publicKey)
|
|
1381
1381
|
};
|
|
1382
1382
|
}
|
|
1383
1383
|
async function de(s) {
|
|
@@ -1385,34 +1385,34 @@ async function de(s) {
|
|
|
1385
1385
|
try {
|
|
1386
1386
|
const i = (t = globalThis.localStorage) == null ? void 0 : t.getItem(`${s}-identity`);
|
|
1387
1387
|
if (i) {
|
|
1388
|
-
const o = JSON.parse(i), r = await
|
|
1388
|
+
const o = JSON.parse(i), r = await I().importKey("jwk", o.ecdhPub, { name: "ECDH", namedCurve: "P-256" }, !0, []), d = await I().importKey("jwk", o.ecdhPriv, { name: "ECDH", namedCurve: "P-256" }, !0, ["deriveKey", "deriveBits"]), u = await I().importKey("jwk", o.ecdsaPub, { name: "ECDSA", namedCurve: "P-256" }, !0, ["verify"]), w = await I().importKey("jwk", o.ecdsaPriv, { name: "ECDSA", namedCurve: "P-256" }, !0, ["sign"]);
|
|
1389
1389
|
return {
|
|
1390
1390
|
ecdhKP: { publicKey: r, privateKey: d },
|
|
1391
|
-
ecdsaKP: { publicKey:
|
|
1392
|
-
publicKeyB64: await
|
|
1393
|
-
sigPublicKeyB64: await
|
|
1391
|
+
ecdsaKP: { publicKey: u, privateKey: w },
|
|
1392
|
+
publicKeyB64: await M(r),
|
|
1393
|
+
sigPublicKeyB64: await M(u)
|
|
1394
1394
|
};
|
|
1395
1395
|
}
|
|
1396
1396
|
} catch {
|
|
1397
1397
|
}
|
|
1398
1398
|
const e = await bt();
|
|
1399
1399
|
try {
|
|
1400
|
-
const i = await
|
|
1400
|
+
const i = await I().exportKey("jwk", e.ecdhKP.publicKey), o = await I().exportKey("jwk", e.ecdhKP.privateKey), r = await I().exportKey("jwk", e.ecdsaKP.publicKey), d = await I().exportKey("jwk", e.ecdsaKP.privateKey);
|
|
1401
1401
|
(n = globalThis.localStorage) == null || n.setItem(`${s}-identity`, JSON.stringify({ ecdhPub: i, ecdhPriv: o, ecdsaPub: r, ecdsaPriv: d }));
|
|
1402
1402
|
} catch {
|
|
1403
1403
|
}
|
|
1404
1404
|
return e;
|
|
1405
1405
|
}
|
|
1406
1406
|
async function mt(s, e) {
|
|
1407
|
-
const t = await
|
|
1407
|
+
const t = await N(), n = await M(t.publicKey), i = await H(e.identityKey), o = await H(e.signedPrekey), r = e.oneTimePrekey ? await H(e.oneTimePrekey) : null, d = await z(s.privateKey, o), u = await z(t.privateKey, i), w = await z(t.privateKey, o), y = r ? await z(t.privateKey, r) : null, x = xe(d, u, w, ...y ? [y] : []);
|
|
1408
1408
|
return { sharedKey: await ge(x), ephemeralPublicKey: n };
|
|
1409
1409
|
}
|
|
1410
1410
|
async function vt(s, e, t, n, i) {
|
|
1411
|
-
const o = await
|
|
1411
|
+
const o = await H(t), r = await H(n), d = await z(e.privateKey, o), u = await z(s.privateKey, r), w = await z(e.privateKey, r), y = i ? await z(i.privateKey, r) : null, x = xe(d, u, w, ...y ? [y] : []);
|
|
1412
1412
|
return ge(x);
|
|
1413
1413
|
}
|
|
1414
|
-
async function
|
|
1415
|
-
return
|
|
1414
|
+
async function z(s, e) {
|
|
1415
|
+
return I().deriveBits({ name: "ECDH", public: e }, s, 256);
|
|
1416
1416
|
}
|
|
1417
1417
|
function xe(...s) {
|
|
1418
1418
|
const e = s.reduce((i, o) => i + o.byteLength, 0), t = new Uint8Array(e);
|
|
@@ -1422,8 +1422,8 @@ function xe(...s) {
|
|
|
1422
1422
|
return t.buffer;
|
|
1423
1423
|
}
|
|
1424
1424
|
async function ge(s) {
|
|
1425
|
-
const e = await
|
|
1426
|
-
return
|
|
1425
|
+
const e = await I().importKey("raw", s, "HKDF", !1, ["deriveKey"]);
|
|
1426
|
+
return I().deriveKey(
|
|
1427
1427
|
{ name: "HKDF", hash: "SHA-256", salt: new Uint8Array(32), info: new TextEncoder().encode("ObjectChat X3DH v1") },
|
|
1428
1428
|
e,
|
|
1429
1429
|
{ name: "AES-GCM", length: 256 },
|
|
@@ -1453,19 +1453,19 @@ class St {
|
|
|
1453
1453
|
}
|
|
1454
1454
|
/** Live ECDH mode: Generate/restore our keypair and return our public key to publish. */
|
|
1455
1455
|
async begin() {
|
|
1456
|
-
return this.kp = await gt(this.storageKey),
|
|
1456
|
+
return this.kp = await gt(this.storageKey), M(this.kp.publicKey);
|
|
1457
1457
|
}
|
|
1458
1458
|
/** Live ECDH mode: A peer published their key — derive the shared secret. */
|
|
1459
1459
|
async onPeerKey(e) {
|
|
1460
|
-
this.kp && (this.shared = await
|
|
1460
|
+
this.kp && (this.shared = await ut(this.kp.privateKey, e));
|
|
1461
1461
|
}
|
|
1462
1462
|
// ── X3DH async mode ────────────────────────────────────────────────────────
|
|
1463
1463
|
/** X3DH: Generate identity key, signed prekey, and OTP prekeys.
|
|
1464
1464
|
* Returns the upload frame payload the caller should send to the server. */
|
|
1465
1465
|
async initX3DH() {
|
|
1466
|
-
this.identityKP = await de(this.storageKey), this.signedPreKP = await
|
|
1467
|
-
for (let i = 0; i < kt; i++) this.otpKeys.push(await
|
|
1468
|
-
const e = await
|
|
1466
|
+
this.identityKP = await de(this.storageKey), this.signedPreKP = await N(), this.signedPrekeyId = `spk-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
1467
|
+
for (let i = 0; i < kt; i++) this.otpKeys.push(await N());
|
|
1468
|
+
const e = await M(this.signedPreKP.publicKey), t = await yt(this.identityKP.ecdsaKP.privateKey, this.signedPreKP.publicKey), n = await Promise.all(this.otpKeys.map((i) => M(i.publicKey)));
|
|
1469
1469
|
return {
|
|
1470
1470
|
identityKey: this.identityKP.publicKeyB64,
|
|
1471
1471
|
signedPrekey: e,
|
|
@@ -1815,70 +1815,70 @@ class At {
|
|
|
1815
1815
|
/** Fetch the list and re-render it. Called on mount and after switching chats. */
|
|
1816
1816
|
a(this, "destroyed", !1);
|
|
1817
1817
|
a(this, "subjectBuilt", !1);
|
|
1818
|
-
var
|
|
1818
|
+
var k, b, E, B, T, A, $, _, D, W;
|
|
1819
1819
|
this.root = e, this.me = t, this.h = n, this.cfg = i, Ut(), e.classList.add("ocw"), i.accent && e.style.setProperty("--ocw-accent", i.accent);
|
|
1820
1820
|
const o = c("div", "ocw-head"), r = c("div", "ocw-avatar");
|
|
1821
|
-
if ((
|
|
1822
|
-
const
|
|
1823
|
-
|
|
1821
|
+
if ((k = i.userInfo) != null && k.avatar) {
|
|
1822
|
+
const S = document.createElement("img");
|
|
1823
|
+
S.src = i.userInfo.avatar, S.alt = i.userInfo.name ?? "You", S.style.cssText = "width:100%;height:100%;border-radius:50%;object-fit:cover", r.append(S);
|
|
1824
1824
|
} else
|
|
1825
|
-
r.textContent = (
|
|
1825
|
+
r.textContent = (b = i.userInfo) != null && b.name ? i.userInfo.name[0].toUpperCase() : "🧑";
|
|
1826
1826
|
o.append(r);
|
|
1827
1827
|
const d = c("div", "ocw-head-main");
|
|
1828
|
-
this.headerName = c("div", "ocw-head-name", ((E = i.subject) == null ? void 0 : E.ownerLabel) ?? ((
|
|
1828
|
+
this.headerName = c("div", "ocw-head-name", ((E = i.subject) == null ? void 0 : E.ownerLabel) ?? ((B = i.subject) == null ? void 0 : B.title) ?? ""), d.append(this.headerName), (T = i.subject) != null && T.subtitle && d.append(c("div", "ocw-head-meta", i.subject.subtitle)), o.append(d), this.statusBadge = c("span", "ocw-badge", ((A = i.subject) == null ? void 0 : A.status) ?? ""), ($ = i.subject) != null && $.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", () => {
|
|
1829
1829
|
this.cobrowseActive = !this.cobrowseActive, this.updateCobrowseUI();
|
|
1830
1830
|
}), o.append(this.cobrowseBtn), this.h.onListChats && (this.backBtn = c("button", "ocw-chat-back", "←"), this.backBtn.addEventListener("click", () => this.showListScreen()), o.prepend(this.backBtn)), 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");
|
|
1831
|
-
const
|
|
1832
|
-
|
|
1833
|
-
for (const
|
|
1834
|
-
const
|
|
1835
|
-
|
|
1831
|
+
const u = c("div", "ocw-typing-bubble");
|
|
1832
|
+
u.append(c("div", "ocw-typing-dot"), c("div", "ocw-typing-dot"), c("div", "ocw-typing-dot")), this.typing.append(c("div", "ocw-dot", "🧑"), u), this.quick = c("div", "ocw-quick");
|
|
1833
|
+
for (const S of i.quickReplies ?? []) {
|
|
1834
|
+
const m = c("button", void 0, S);
|
|
1835
|
+
m.addEventListener("click", () => this.h.onSend(S)), this.quick.append(m);
|
|
1836
1836
|
}
|
|
1837
1837
|
this.formHost = c("div", "ocw-form-host"), this.csatPanel = c("div", "ocw-csat"), this.csatPanel.style.display = "none", this.offlinePanel = c("div", "ocw-offline"), this.offlinePanel.style.display = "none", this.input = c("textarea", void 0), this.input.rows = 1, this.input.placeholder = "Message…";
|
|
1838
|
-
const w = c("button", "ocw-sendbtn", ((
|
|
1839
|
-
w.addEventListener("click", () => this.flushSend()), this.input.addEventListener("keydown", (
|
|
1840
|
-
|
|
1838
|
+
const w = c("button", "ocw-sendbtn", ((_ = i.i18n) == null ? void 0 : _.send) ?? "➤");
|
|
1839
|
+
w.addEventListener("click", () => this.flushSend()), this.input.addEventListener("keydown", (S) => {
|
|
1840
|
+
S.isComposing || S.keyCode === 229 || (S.key === "Enter" && !S.shiftKey ? (S.preventDefault(), this.flushSend()) : this.signalTyping());
|
|
1841
1841
|
});
|
|
1842
|
-
const
|
|
1843
|
-
|
|
1842
|
+
const y = c("button", "ocw-attach", "📎");
|
|
1843
|
+
y.title = "Attach image or file";
|
|
1844
1844
|
const x = document.createElement("input");
|
|
1845
|
-
x.type = "file", x.accept = "image/*,.pdf,.txt,.doc,.docx", x.style.display = "none",
|
|
1846
|
-
var
|
|
1847
|
-
(
|
|
1845
|
+
x.type = "file", x.accept = "image/*,.pdf,.txt,.doc,.docx", x.style.display = "none", y.addEventListener("click", () => x.click()), x.addEventListener("change", () => {
|
|
1846
|
+
var S;
|
|
1847
|
+
(S = x.files) != null && S[0] && this.h.onAttach && this.h.onAttach(x.files[0]), x.value = "";
|
|
1848
1848
|
});
|
|
1849
|
-
const
|
|
1850
|
-
|
|
1849
|
+
const p = c("div", "ocw-input");
|
|
1850
|
+
p.append(y, x, this.input, w);
|
|
1851
1851
|
const h = c("div", "ocw-footer");
|
|
1852
|
-
if (h.innerHTML = ((
|
|
1853
|
-
const
|
|
1854
|
-
|
|
1855
|
-
const
|
|
1856
|
-
|
|
1857
|
-
var
|
|
1858
|
-
(
|
|
1859
|
-
}),
|
|
1860
|
-
const V = c("div", "ocw-cl-search-wrap"),
|
|
1861
|
-
|
|
1862
|
-
const
|
|
1863
|
-
|
|
1864
|
-
const
|
|
1865
|
-
|
|
1852
|
+
if (h.innerHTML = ((D = i.i18n) == null ? void 0 : D.poweredBy) !== void 0 ? i.i18n.poweredBy : 'Powered by <a href="https://relay.paramms.com" target="_blank" rel="noopener">Relay</a>', this.footer = h, this.h.onListChats) {
|
|
1853
|
+
const S = c("div", "ocw-screen ocw-screen-list"), m = c("div", "ocw-cl-head");
|
|
1854
|
+
m.append(c("span", "ocw-cl-title", "Messages"));
|
|
1855
|
+
const q = c("button", "ocw-cl-new", "+");
|
|
1856
|
+
q.title = "New conversation", q.addEventListener("click", () => {
|
|
1857
|
+
var f, g;
|
|
1858
|
+
(g = (f = this.h).onSwitchChat) == null || g.call(f, { id: "__new__", state: "open", updatedAt: Date.now() });
|
|
1859
|
+
}), m.append(q);
|
|
1860
|
+
const V = c("div", "ocw-cl-search-wrap"), P = c("input", "ocw-cl-search");
|
|
1861
|
+
P.placeholder = "🔍 Search", P.type = "search", P.addEventListener("input", () => this.renderListRows(this.allEntries, P.value.trim().toLowerCase())), V.append(P);
|
|
1862
|
+
const R = c("div", "ocw-cl-body-scroll");
|
|
1863
|
+
R.append(c("div", "ocw-cl-section", "Loading…")), S.append(m, V, R), e.append(S), this.listScreen = S, this.listBody = R, this.listSearch = P;
|
|
1864
|
+
const l = c("div", "ocw-screen ocw-screen-chat");
|
|
1865
|
+
l.append(o, this.chips, this.scroll, this.typing, this.quick, this.formHost, this.csatPanel, this.offlinePanel, p, this.footer), e.append(l), this.chatScreen = l, i.startOnChat ? (this.inChatScreen = !0, this.listScreen.classList.add("hidden"), this.chatScreen.classList.add("visible"), (W = this.backBtn) == null || W.classList.add("show")) : this.inChatScreen = !1, this.refreshList();
|
|
1866
1866
|
} else
|
|
1867
|
-
e.append(o, this.chips, this.scroll, this.typing, this.quick, this.formHost, this.csatPanel, this.offlinePanel,
|
|
1867
|
+
e.append(o, this.chips, this.scroll, this.typing, this.quick, this.formHost, this.csatPanel, this.offlinePanel, p, this.footer);
|
|
1868
1868
|
this.cobrowseCanvas = c("canvas", "ocw-cobrowse-canvas"), this.cobrowseToolbar = c("div", "ocw-cobrowse-toolbar");
|
|
1869
|
-
for (const
|
|
1870
|
-
const
|
|
1871
|
-
|
|
1872
|
-
this.cobrowseColor =
|
|
1873
|
-
for (const
|
|
1874
|
-
|
|
1875
|
-
}), this.cobrowseToolbar.append(
|
|
1869
|
+
for (const S of ["#f5713c", "#1c1b1a", "#2563eb", "#16a34a", "#dc2626"]) {
|
|
1870
|
+
const m = c("button", "ocw-cobrowse-swatch");
|
|
1871
|
+
m.style.background = S, m.type = "button", S === this.cobrowseColor && m.classList.add("sel"), m.addEventListener("click", () => {
|
|
1872
|
+
this.cobrowseColor = S;
|
|
1873
|
+
for (const q of this.cobrowseToolbar.querySelectorAll(".ocw-cobrowse-swatch")) q.classList.remove("sel");
|
|
1874
|
+
m.classList.add("sel");
|
|
1875
|
+
}), this.cobrowseToolbar.append(m);
|
|
1876
1876
|
}
|
|
1877
|
-
const
|
|
1878
|
-
|
|
1879
|
-
var
|
|
1880
|
-
return (
|
|
1881
|
-
}), this.cobrowseToolbar.append(
|
|
1877
|
+
const v = c("button", "ocw-cobrowse-clear", "Clear");
|
|
1878
|
+
v.addEventListener("click", () => {
|
|
1879
|
+
var S, m;
|
|
1880
|
+
return (m = (S = this.h).onAnnotateClear) == null ? void 0 : m.call(S);
|
|
1881
|
+
}), this.cobrowseToolbar.append(v), this.cobrowseHint = c("div", "ocw-cobrowse-hint", "🖍 Draw to point things out — visible to both sides"), e.append(this.cobrowseCanvas, this.cobrowseToolbar, this.cobrowseHint), this.bindCobrowsePointerEvents();
|
|
1882
1882
|
}
|
|
1883
1883
|
/** Returns the scroll container so history.ts can attach scroll listeners. */
|
|
1884
1884
|
getScrollEl() {
|
|
@@ -1949,22 +1949,22 @@ class At {
|
|
|
1949
1949
|
}
|
|
1950
1950
|
/** Build a single WhatsApp-style conversation row. */
|
|
1951
1951
|
buildRow(e) {
|
|
1952
|
-
var
|
|
1953
|
-
const t = this.seenSeq.get(e.id) ?? 0, n = e.lastSeq ?? 0, i = this.isUnread(e) ? Math.max(1, n - t) : 0, o = e.subjectTitle ?? "General enquiry", r = ((
|
|
1954
|
-
e.state === "open" ? w.classList.add("open") : e.state === "awaiting_staff" && w.classList.add("waiting"),
|
|
1955
|
-
const
|
|
1956
|
-
|
|
1952
|
+
var v;
|
|
1953
|
+
const t = this.seenSeq.get(e.id) ?? 0, n = e.lastSeq ?? 0, i = this.isUnread(e) ? Math.max(1, n - t) : 0, o = e.subjectTitle ?? "General enquiry", r = ((v = o[0]) == null ? void 0 : v.toUpperCase()) ?? "?", d = c("button", `ocw-cl-row${i > 0 ? " unread" : ""}`), u = c("div", "ocw-cl-av", r), w = c("div", "ocw-cl-status");
|
|
1954
|
+
e.state === "open" ? w.classList.add("open") : e.state === "awaiting_staff" && w.classList.add("waiting"), u.append(w), d.append(u);
|
|
1955
|
+
const y = c("div", "ocw-cl-body");
|
|
1956
|
+
y.append(c("div", "ocw-cl-name", o));
|
|
1957
1957
|
const x = {
|
|
1958
1958
|
open: "Conversation open",
|
|
1959
1959
|
awaiting_staff: "Waiting for reply…",
|
|
1960
1960
|
resolved: "Conversation resolved ✓",
|
|
1961
1961
|
closed: "Conversation closed"
|
|
1962
|
-
},
|
|
1963
|
-
|
|
1962
|
+
}, p = e.lastMessage ?? x[e.state] ?? e.state;
|
|
1963
|
+
y.append(c("div", "ocw-cl-preview", p)), d.append(y);
|
|
1964
1964
|
const h = c("div", "ocw-cl-right");
|
|
1965
1965
|
return h.append(c("div", "ocw-cl-time", Bt(e.updatedAt))), i > 0 && h.append(c("div", "ocw-cl-badge", String(i > 99 ? "99+" : i))), d.append(h), d.addEventListener("click", () => {
|
|
1966
|
-
var
|
|
1967
|
-
n > 0 && this.seenSeq.set(e.id, n), this.activeChatId = e.id, this.showChatScreen(), (
|
|
1966
|
+
var k, b;
|
|
1967
|
+
n > 0 && this.seenSeq.set(e.id, n), this.activeChatId = e.id, this.showChatScreen(), (b = (k = this.h).onSwitchChat) == null || b.call(k, e);
|
|
1968
1968
|
}), d;
|
|
1969
1969
|
}
|
|
1970
1970
|
/** Returns true when the chat screen is visible (not the list). */
|
|
@@ -1989,30 +1989,30 @@ class At {
|
|
|
1989
1989
|
this.h.onTyping(!0), this.typingTimer && clearTimeout(this.typingTimer), this.typingTimer = setTimeout(() => this.h.onTyping(!1), 2e3);
|
|
1990
1990
|
}
|
|
1991
1991
|
render(e) {
|
|
1992
|
-
var w,
|
|
1992
|
+
var w, y, x;
|
|
1993
1993
|
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) {
|
|
1994
|
-
const
|
|
1995
|
-
|
|
1994
|
+
const p = (w = this.cfg.subject) == null ? void 0 : w.ownerLabel;
|
|
1995
|
+
p && (this.headerName.textContent = p);
|
|
1996
1996
|
}
|
|
1997
1997
|
this.chips.replaceChildren();
|
|
1998
1998
|
const t = e.visibleActions();
|
|
1999
1999
|
this.chips.style.display = t.length ? "flex" : "none";
|
|
2000
|
-
for (const
|
|
2000
|
+
for (const p of t) this.chips.append(this.chipEl(p));
|
|
2001
2001
|
const n = this.scroll.scrollHeight, i = this.scroll.scrollTop;
|
|
2002
2002
|
if (this.scroll.replaceChildren(), this.subjectCard.childNodes.length && this.scroll.append(this.subjectCard), e.hasMoreHistory) {
|
|
2003
|
-
const
|
|
2004
|
-
|
|
2003
|
+
const p = c("div", "ocw-load-more");
|
|
2004
|
+
p.textContent = "↑ Loading earlier messages…", p.style.pointerEvents = "none", this.scroll.append(p);
|
|
2005
2005
|
}
|
|
2006
2006
|
let o = 0;
|
|
2007
|
-
for (const
|
|
2008
|
-
this.scroll.append(this.messageEl(
|
|
2007
|
+
for (const p of e.messages())
|
|
2008
|
+
this.scroll.append(this.messageEl(p, e)), p.senderId !== this.me && p.seq > o && (o = p.seq);
|
|
2009
2009
|
i > 20 ? this.scroll.scrollTop = this.scroll.scrollHeight - n + i : this.scroll.scrollTop = this.scroll.scrollHeight, o > 0 && this.h.onReadUpTo(o);
|
|
2010
2010
|
const r = [...e.typing];
|
|
2011
2011
|
this.typing.classList.toggle("active", r.length > 0);
|
|
2012
2012
|
const d = this.typing.querySelector(".ocw-typing-bubble");
|
|
2013
|
-
d && d.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", (
|
|
2014
|
-
const
|
|
2015
|
-
this.h.onCsat && !this.csatSubmitted &&
|
|
2013
|
+
d && d.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", (y = this.root.querySelector(".ocw-input")) == null || y.style.setProperty("display", "none")) : (this.offlinePanel.style.display = "none", (x = this.root.querySelector(".ocw-input")) == null || x.style.removeProperty("display"));
|
|
2014
|
+
const u = ["resolved", "closed", "sold", "issued", "checked_out"];
|
|
2015
|
+
this.h.onCsat && !this.csatSubmitted && u.includes(e.state) && e.messages().length > 0 && (this.csatPanel.style.display === "none" && this.buildCsatPanel(), this.csatPanel.style.display = "block");
|
|
2016
2016
|
}
|
|
2017
2017
|
setConnStatus(e) {
|
|
2018
2018
|
if (e === "open") {
|
|
@@ -2080,8 +2080,8 @@ Message: ${o.value}`), this.offlinePanel.replaceChildren(c("div", "ocw-offline-t
|
|
|
2080
2080
|
bindCobrowsePointerEvents() {
|
|
2081
2081
|
let e = !1, t = [];
|
|
2082
2082
|
const n = (r) => {
|
|
2083
|
-
const d = this.cobrowseCanvas.getBoundingClientRect(),
|
|
2084
|
-
return { x: Math.min(1, Math.max(0,
|
|
2083
|
+
const d = this.cobrowseCanvas.getBoundingClientRect(), u = d.width > 0 ? (r.clientX - d.left) / d.width : 0, w = d.height > 0 ? (r.clientY - d.top) / d.height : 0;
|
|
2084
|
+
return { x: Math.min(1, Math.max(0, u)), y: Math.min(1, Math.max(0, w)) };
|
|
2085
2085
|
}, i = 6e-3;
|
|
2086
2086
|
this.cobrowseCanvas.addEventListener("pointerdown", (r) => {
|
|
2087
2087
|
this.cobrowseActive && (e = !0, t = [n(r)], this.cobrowseCanvas.setPointerCapture(r.pointerId));
|
|
@@ -2089,9 +2089,9 @@ Message: ${o.value}`), this.offlinePanel.replaceChildren(c("div", "ocw-offline-t
|
|
|
2089
2089
|
e && (t.push(n(r)), this.redrawCobrowse(), this.drawStroke({ points: t, color: this.cobrowseColor, width: i }));
|
|
2090
2090
|
});
|
|
2091
2091
|
const o = (r) => {
|
|
2092
|
-
var d,
|
|
2092
|
+
var d, u;
|
|
2093
2093
|
if (e) {
|
|
2094
|
-
e = !1, t.length > 1 && ((
|
|
2094
|
+
e = !1, t.length > 1 && ((u = (d = this.h).onAnnotate) == null || u.call(d, { id: `an_${Date.now()}_${Math.random().toString(36).slice(2)}`, points: t, color: this.cobrowseColor, width: i })), t = [];
|
|
2095
2095
|
try {
|
|
2096
2096
|
this.cobrowseCanvas.releasePointerCapture(r.pointerId);
|
|
2097
2097
|
} catch {
|
|
@@ -2106,7 +2106,7 @@ Message: ${o.value}`), this.offlinePanel.replaceChildren(c("div", "ocw-offline-t
|
|
|
2106
2106
|
if (!i) return;
|
|
2107
2107
|
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));
|
|
2108
2108
|
const o = c("div", "ocw-tags");
|
|
2109
|
-
if (t) for (const [d,
|
|
2109
|
+
if (t) for (const [d, u] of Object.entries(t.fields)) o.append(c("span", "ocw-tag", `${d}: ${u}`));
|
|
2110
2110
|
else for (const d of (n == null ? void 0 : n.tags) ?? []) o.append(c("span", "ocw-tag", d));
|
|
2111
2111
|
o.childNodes.length && this.subjectCard.append(o);
|
|
2112
2112
|
const r = (t == null ? void 0 : t.state) ?? (n == null ? void 0 : n.status);
|
|
@@ -2124,161 +2124,161 @@ Message: ${o.value}`), this.offlinePanel.replaceChildren(c("div", "ocw-offline-t
|
|
|
2124
2124
|
return new Promise((t) => {
|
|
2125
2125
|
const n = c("div", "ocw-modal"), i = c("div", "ocw-modal-card");
|
|
2126
2126
|
i.append(c("div", "ocw-modal-title", e)), i.append(c("div", "ocw-modal-body", `Confirm “${e}”?`));
|
|
2127
|
-
const o = c("div", "ocw-modal-actions"), r = c("button", "ocw-modal-cancel", "Cancel"), d = c("button", "ocw-modal-ok", "Confirm"),
|
|
2127
|
+
const o = c("div", "ocw-modal-actions"), r = c("button", "ocw-modal-cancel", "Cancel"), d = c("button", "ocw-modal-ok", "Confirm"), u = (w) => {
|
|
2128
2128
|
n.remove(), t(w);
|
|
2129
2129
|
};
|
|
2130
|
-
r.addEventListener("click", () =>
|
|
2131
|
-
w.target === n &&
|
|
2130
|
+
r.addEventListener("click", () => u(!1)), d.addEventListener("click", () => u(!0)), n.addEventListener("click", (w) => {
|
|
2131
|
+
w.target === n && u(!1);
|
|
2132
2132
|
}), o.append(r, d), i.append(o), n.append(i), this.root.append(n), d.focus();
|
|
2133
2133
|
});
|
|
2134
2134
|
}
|
|
2135
2135
|
/** Inline form for a form-effect action: typed inputs (date picker, number,
|
|
2136
2136
|
* text) rendered above the composer — no browser prompts. */
|
|
2137
2137
|
openForm(e) {
|
|
2138
|
-
var d,
|
|
2138
|
+
var d, u;
|
|
2139
2139
|
this.formHost.replaceChildren();
|
|
2140
2140
|
const t = c("div", "ocw-form");
|
|
2141
2141
|
t.append(c("div", "ocw-form-title", e.icon ? `${e.icon} ${e.label}` : e.label));
|
|
2142
2142
|
const n = /* @__PURE__ */ new Map();
|
|
2143
2143
|
for (const w of e.input ?? []) {
|
|
2144
|
-
const
|
|
2145
|
-
if (
|
|
2144
|
+
const y = c("label", "ocw-form-row");
|
|
2145
|
+
if (y.append(c("span", "ocw-form-lbl", w.label)), w.type === "select" && ((d = w.options) != null && d.length)) {
|
|
2146
2146
|
const x = c("select", "ocw-form-input");
|
|
2147
2147
|
w.required || x.append(c("option", void 0, "— select —"));
|
|
2148
|
-
for (const
|
|
2148
|
+
for (const p of w.options) {
|
|
2149
2149
|
const h = c("option");
|
|
2150
|
-
h.value =
|
|
2150
|
+
h.value = p, h.textContent = p, x.append(h);
|
|
2151
2151
|
}
|
|
2152
|
-
w.required && (x.required = !0),
|
|
2152
|
+
w.required && (x.required = !0), y.append(x), n.set(w.name, x);
|
|
2153
2153
|
} else {
|
|
2154
2154
|
const x = c("input", "ocw-form-input");
|
|
2155
|
-
x.type = w.type === "number" ? "number" : w.type === "date" ? "datetime-local" : "text", w.required && (x.required = !0),
|
|
2155
|
+
x.type = w.type === "number" ? "number" : w.type === "date" ? "datetime-local" : "text", w.required && (x.required = !0), y.append(x), n.set(w.name, x);
|
|
2156
2156
|
}
|
|
2157
|
-
t.append(
|
|
2157
|
+
t.append(y);
|
|
2158
2158
|
}
|
|
2159
2159
|
const i = c("div", "ocw-form-actions"), o = c("button", "ocw-form-cancel", "Cancel"), r = c("button", "ocw-form-submit", "Send");
|
|
2160
2160
|
o.addEventListener("click", () => this.formHost.replaceChildren()), r.addEventListener("click", () => {
|
|
2161
2161
|
const w = {};
|
|
2162
|
-
for (const [
|
|
2162
|
+
for (const [y, x] of n) {
|
|
2163
2163
|
if (x.required && !x.value) {
|
|
2164
2164
|
x.style.borderColor = "#e5484d";
|
|
2165
2165
|
return;
|
|
2166
2166
|
}
|
|
2167
|
-
w[
|
|
2167
|
+
w[y] = x.type === "number" ? Number(x.value) : x.value;
|
|
2168
2168
|
}
|
|
2169
2169
|
this.formHost.replaceChildren(), this.h.onInvoke(e.id, w);
|
|
2170
|
-
}), i.append(o, r), t.append(i), this.formHost.append(t), (
|
|
2170
|
+
}), i.append(o, r), t.append(i), this.formHost.append(t), (u = n.values().next().value) == null || u.focus();
|
|
2171
2171
|
}
|
|
2172
2172
|
messageEl(e, t) {
|
|
2173
2173
|
var x;
|
|
2174
2174
|
if (e.senderRole === "system") {
|
|
2175
|
-
const
|
|
2176
|
-
return
|
|
2175
|
+
const p = c("div", "ocw-sys");
|
|
2176
|
+
return p.textContent = e.deletedAt ? "message deleted" : Q(e.content), p;
|
|
2177
2177
|
}
|
|
2178
2178
|
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" : ""}`);
|
|
2179
2179
|
!n && !i && o.append(c("div", "ocw-dot", e.senderRole === "bot" ? "🤖" : "🧑"));
|
|
2180
2180
|
const r = c("div"), d = c("div", "ocw-bubble-wrap");
|
|
2181
2181
|
if (e.replyToId) {
|
|
2182
|
-
const
|
|
2183
|
-
|
|
2182
|
+
const p = c("div", "ocw-reply-to", "↩ replying to a message");
|
|
2183
|
+
p.style.cssText = "font-size:11px;color:var(--ocw-mut);margin-bottom:2px;font-style:italic", r.append(p);
|
|
2184
2184
|
}
|
|
2185
|
-
const
|
|
2185
|
+
const u = c("div", "ocw-bubble");
|
|
2186
2186
|
let w = null;
|
|
2187
|
-
if (e.deletedAt)
|
|
2187
|
+
if (e.deletedAt) u.append(c("span", "ocw-deleted", "message deleted"));
|
|
2188
2188
|
else if (e.content.kind === "attachment") {
|
|
2189
|
-
const
|
|
2190
|
-
if ((x =
|
|
2189
|
+
const p = e.content;
|
|
2190
|
+
if ((x = p.mime) != null && x.startsWith("image/")) {
|
|
2191
2191
|
const h = document.createElement("img");
|
|
2192
|
-
h.src =
|
|
2192
|
+
h.src = p.url, h.alt = p.name ?? "image", h.style.cssText = "max-width:220px;max-height:160px;border-radius:10px;display:block;cursor:pointer", h.addEventListener("click", () => window.open(p.url, "_blank")), u.append(h);
|
|
2193
2193
|
} else {
|
|
2194
2194
|
const h = document.createElement("a");
|
|
2195
|
-
h.href =
|
|
2195
|
+
h.href = p.url, h.target = "_blank", h.rel = "noopener", h.style.cssText = "display:flex;align-items:center;gap:8px;color:inherit;text-decoration:none", h.append(c("span", void 0, "📄"), c("span", void 0, p.name ?? "file")), u.append(h);
|
|
2196
2196
|
}
|
|
2197
2197
|
} else if (e.content.kind === "appointment") {
|
|
2198
|
-
const
|
|
2199
|
-
h.append(c("div", "ocw-appt-title", `📅 ${
|
|
2200
|
-
const
|
|
2201
|
-
|
|
2202
|
-
const
|
|
2203
|
-
|
|
2198
|
+
const p = e.content, h = c("div", "ocw-appt");
|
|
2199
|
+
h.append(c("div", "ocw-appt-title", `📅 ${p.title}`)), h.append(c("div", "ocw-appt-time", new Date(p.startIso).toLocaleString() + " – " + new Date(p.endIso).toLocaleTimeString())), p.location && h.append(c("div", "ocw-appt-loc", `📍 ${p.location}`)), p.description && h.append(c("div", "ocw-appt-desc", p.description));
|
|
2200
|
+
const v = c("div", "ocw-appt-links"), k = document.createElement("a");
|
|
2201
|
+
k.href = p.googleUrl, k.target = "_blank", k.rel = "noopener", k.className = "ocw-appt-btn", k.textContent = "📅 Add to Google Calendar";
|
|
2202
|
+
const b = document.createElement("a");
|
|
2203
|
+
b.href = p.icalUrl, b.download = `${p.title}.ics`, b.className = "ocw-appt-btn ocw-appt-btn-sec", b.textContent = "🍎 Apple / iCal", v.append(k, b), h.append(v), u.append(h);
|
|
2204
2204
|
} else
|
|
2205
|
-
w = document.createTextNode(Q(e.content)),
|
|
2206
|
-
if (d.append(
|
|
2207
|
-
const
|
|
2208
|
-
if (
|
|
2205
|
+
w = document.createTextNode(Q(e.content)), u.append(w), e.editedAt && u.append(c("span", "ocw-edited", "(edited)"));
|
|
2206
|
+
if (d.append(u), !n && !i && this.h.onTranslate && e.content.kind === "text" && !e.deletedAt && e.seq > 0 && w) {
|
|
2207
|
+
const p = e.content.text;
|
|
2208
|
+
if (p.trim()) {
|
|
2209
2209
|
const h = c("button", "ocw-translate-btn", "🌐");
|
|
2210
|
-
h.type = "button", h.title = "Translate", h.addEventListener("click", (
|
|
2211
|
-
if (
|
|
2212
|
-
this.showingTranslation.delete(e.id), w.textContent =
|
|
2210
|
+
h.type = "button", h.title = "Translate", h.addEventListener("click", (v) => {
|
|
2211
|
+
if (v.stopPropagation(), this.showingTranslation.has(e.id)) {
|
|
2212
|
+
this.showingTranslation.delete(e.id), w.textContent = p, h.textContent = "🌐", h.title = "Translate";
|
|
2213
2213
|
return;
|
|
2214
2214
|
}
|
|
2215
|
-
const
|
|
2216
|
-
if (
|
|
2217
|
-
this.showingTranslation.add(e.id), w.textContent =
|
|
2215
|
+
const k = this.translationCache.get(e.id);
|
|
2216
|
+
if (k !== void 0) {
|
|
2217
|
+
this.showingTranslation.add(e.id), w.textContent = k, h.textContent = "↩", h.title = "Show original";
|
|
2218
2218
|
return;
|
|
2219
2219
|
}
|
|
2220
|
-
h.textContent = "⏳", this.h.onTranslate(
|
|
2221
|
-
if (
|
|
2220
|
+
h.textContent = "⏳", this.h.onTranslate(p).then((b) => {
|
|
2221
|
+
if (b === null) {
|
|
2222
2222
|
h.textContent = "⚠️", h.title = "Translation unavailable", setTimeout(() => {
|
|
2223
2223
|
h.textContent = "🌐", h.title = "Translate";
|
|
2224
2224
|
}, 1500);
|
|
2225
2225
|
return;
|
|
2226
2226
|
}
|
|
2227
|
-
this.translationCache.set(e.id,
|
|
2227
|
+
this.translationCache.set(e.id, b), this.showingTranslation.add(e.id), w.textContent = b, h.textContent = "↩", h.title = "Show original";
|
|
2228
2228
|
});
|
|
2229
2229
|
}), d.append(h);
|
|
2230
2230
|
}
|
|
2231
2231
|
}
|
|
2232
2232
|
if (n && !e.deletedAt && e.seq > 0 && (this.h.onEdit ?? this.h.onDelete)) {
|
|
2233
|
-
const
|
|
2233
|
+
const p = c("div", "ocw-msg-menu");
|
|
2234
2234
|
if (this.h.onEdit) {
|
|
2235
2235
|
const h = c("button", void 0, "✏️");
|
|
2236
|
-
h.title = "Edit", h.addEventListener("click", (
|
|
2237
|
-
|
|
2238
|
-
const
|
|
2239
|
-
|
|
2240
|
-
}),
|
|
2236
|
+
h.title = "Edit", h.addEventListener("click", (v) => {
|
|
2237
|
+
v.stopPropagation();
|
|
2238
|
+
const k = Q(e.content), b = prompt("Edit message:", k);
|
|
2239
|
+
b !== null && b.trim() && b !== k && this.h.onEdit(e.id, b.trim());
|
|
2240
|
+
}), p.append(h);
|
|
2241
2241
|
}
|
|
2242
2242
|
if (this.h.onDelete) {
|
|
2243
2243
|
const h = c("button", "del", "🗑");
|
|
2244
|
-
h.title = "Delete", h.addEventListener("click", (
|
|
2245
|
-
|
|
2246
|
-
}),
|
|
2244
|
+
h.title = "Delete", h.addEventListener("click", (v) => {
|
|
2245
|
+
v.stopPropagation(), this.h.onDelete(e.id);
|
|
2246
|
+
}), p.append(h);
|
|
2247
2247
|
}
|
|
2248
|
-
d.append(
|
|
2248
|
+
d.append(p);
|
|
2249
2249
|
}
|
|
2250
2250
|
if (r.append(d), this.h.onReact && !e.deletedAt && e.seq > 0) {
|
|
2251
|
-
const
|
|
2251
|
+
const p = c("div", "ocw-react-wrap"), h = c("div", "ocw-react");
|
|
2252
2252
|
if (e.reactions && Object.keys(e.reactions).length)
|
|
2253
|
-
for (const [
|
|
2254
|
-
const
|
|
2255
|
-
|
|
2256
|
-
var
|
|
2257
|
-
return (
|
|
2258
|
-
}), h.append(
|
|
2253
|
+
for (const [b, E] of Object.entries(e.reactions)) {
|
|
2254
|
+
const B = c("button", `ocw-react-pill${E.includes(this.me) ? " mine" : ""}`, `${b} ${E.length}`);
|
|
2255
|
+
B.addEventListener("click", () => {
|
|
2256
|
+
var T, A;
|
|
2257
|
+
return (A = (T = this.h).onReact) == null ? void 0 : A.call(T, e.id, b, E.includes(this.me));
|
|
2258
|
+
}), h.append(B);
|
|
2259
2259
|
}
|
|
2260
|
-
const
|
|
2261
|
-
for (const
|
|
2262
|
-
const E = c("button", void 0,
|
|
2263
|
-
E.addEventListener("click", (
|
|
2264
|
-
var
|
|
2265
|
-
|
|
2266
|
-
const
|
|
2267
|
-
(
|
|
2268
|
-
}),
|
|
2260
|
+
const v = c("button", "ocw-react-btn", "+"), k = c("div", "ocw-react-picker");
|
|
2261
|
+
for (const b of It) {
|
|
2262
|
+
const E = c("button", void 0, b);
|
|
2263
|
+
E.addEventListener("click", (B) => {
|
|
2264
|
+
var A, $, _, D;
|
|
2265
|
+
B.stopPropagation();
|
|
2266
|
+
const T = ($ = (A = e.reactions) == null ? void 0 : A[b]) == null ? void 0 : $.includes(this.me);
|
|
2267
|
+
(D = (_ = this.h).onReact) == null || D.call(_, e.id, b, !!T), k.style.display = "none";
|
|
2268
|
+
}), k.append(E);
|
|
2269
2269
|
}
|
|
2270
|
-
|
|
2271
|
-
|
|
2270
|
+
k.style.display = "none", v.addEventListener("click", (b) => {
|
|
2271
|
+
b.stopPropagation(), k.style.display = k.style.display === "none" ? "flex" : "none";
|
|
2272
2272
|
}), document.addEventListener("click", () => {
|
|
2273
|
-
|
|
2274
|
-
}, { once: !0 }), h.append(
|
|
2275
|
-
} else e.reactions && Object.keys(e.reactions).length && r.append(c("div", "ocw-react", Object.entries(e.reactions).map(([
|
|
2276
|
-
const
|
|
2273
|
+
k.style.display = "none";
|
|
2274
|
+
}, { once: !0 }), h.append(v), p.append(h, k), r.append(p);
|
|
2275
|
+
} else e.reactions && Object.keys(e.reactions).length && r.append(c("div", "ocw-react", Object.entries(e.reactions).map(([p, h]) => `${p}${h.length}`).join(" ")));
|
|
2276
|
+
const y = c("div", "ocw-time ocw-meta", Tt(e.ts));
|
|
2277
2277
|
if (n && e.status) {
|
|
2278
|
-
const
|
|
2279
|
-
|
|
2278
|
+
const p = c("span", `ocw-tick${e.status === "read" ? " read" : e.status === "delivered" ? " delivered" : ""}`, Pt(e.status));
|
|
2279
|
+
y.append(p);
|
|
2280
2280
|
}
|
|
2281
|
-
return n && e.seq > 0 && t.lastReadByOthers >= e.seq &&
|
|
2281
|
+
return n && e.seq > 0 && t.lastReadByOthers >= e.seq && y.append(c("span", "ocw-seen", " · Seen")), r.append(y), o.append(r), o;
|
|
2282
2282
|
}
|
|
2283
2283
|
}
|
|
2284
2284
|
function Pt(s) {
|
|
@@ -2319,24 +2319,24 @@ async function zt(s, e, t, n, i) {
|
|
|
2319
2319
|
const o = ye(s), r = await he(o, t, e, Number.MAX_SAFE_INTEGER);
|
|
2320
2320
|
if (!r || (r.messages.length ? (n.apply({ type: "sync", conversationId: t, messages: r.messages }), n.apply({ type: "history", conversationId: t, messages: [], hasMore: r.hasMore }), i.render(n)) : n.apply({ type: "history", conversationId: t, messages: [], hasMore: !1 }), !r.hasMore)) return;
|
|
2321
2321
|
let d = !1;
|
|
2322
|
-
const
|
|
2322
|
+
const u = async () => {
|
|
2323
2323
|
if (d || !n.hasMoreHistory) return;
|
|
2324
2324
|
d = !0;
|
|
2325
|
-
const
|
|
2326
|
-
if (!
|
|
2325
|
+
const p = n.messages()[0];
|
|
2326
|
+
if (!p) {
|
|
2327
2327
|
d = !1;
|
|
2328
2328
|
return;
|
|
2329
2329
|
}
|
|
2330
|
-
const h = await he(o, t, e,
|
|
2330
|
+
const h = await he(o, t, e, p.seq);
|
|
2331
2331
|
h && (n.apply({ type: "history", conversationId: t, messages: h.messages, hasMore: h.hasMore }), i.render(n)), d = !1;
|
|
2332
2332
|
}, w = i.getScrollEl();
|
|
2333
2333
|
if (!w) return;
|
|
2334
|
-
let
|
|
2334
|
+
let y = !1;
|
|
2335
2335
|
setTimeout(() => {
|
|
2336
|
-
|
|
2336
|
+
y = !0;
|
|
2337
2337
|
}, 300);
|
|
2338
2338
|
const x = () => {
|
|
2339
|
-
|
|
2339
|
+
y && w.scrollTop < 80 && n.hasMoreHistory && !d && u();
|
|
2340
2340
|
};
|
|
2341
2341
|
w.addEventListener("scroll", x, { passive: !0 }), i.setScrollCleanup(() => w.removeEventListener("scroll", x));
|
|
2342
2342
|
}
|
|
@@ -2352,80 +2352,117 @@ function Mt() {
|
|
|
2352
2352
|
}
|
|
2353
2353
|
}
|
|
2354
2354
|
function $t(s) {
|
|
2355
|
-
var
|
|
2356
|
-
const e = s.token ?? Mt(), t = new dt(e), n = new
|
|
2355
|
+
var P, R;
|
|
2356
|
+
const e = s.token ?? Mt(), t = new dt(e), n = new ft(e);
|
|
2357
2357
|
let i, o = !1, r = null;
|
|
2358
2358
|
!s.launcher && !s.el.style.height && s.el.clientHeight === 0 && (s.el.style.width = s.el.style.width || "100%", s.el.style.height = "600px");
|
|
2359
2359
|
for (const l of n.load()) t.addOptimistic(l.clientMsgId, l.content);
|
|
2360
|
-
let d = null,
|
|
2360
|
+
let d = null, u = null, w = 0, y = !s.launcher;
|
|
2361
2361
|
if (s.launcher) {
|
|
2362
|
-
const
|
|
2363
|
-
d = document.createElement("div"), d.style.cssText = `position:fixed;${
|
|
2364
|
-
const
|
|
2365
|
-
|
|
2366
|
-
|
|
2362
|
+
const f = (s.position ?? "bottom-right").includes("right");
|
|
2363
|
+
d = document.createElement("div"), d.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`;
|
|
2364
|
+
const g = document.createElement("div");
|
|
2365
|
+
g.style.cssText = [
|
|
2366
|
+
"width:380px",
|
|
2367
|
+
"height:600px",
|
|
2368
|
+
"border-radius:16px",
|
|
2369
|
+
"overflow:hidden",
|
|
2370
|
+
"box-shadow:0 8px 40px rgba(0,0,0,.18)",
|
|
2371
|
+
"display:none",
|
|
2372
|
+
// hidden until bubble clicked
|
|
2373
|
+
"flex-direction:column",
|
|
2374
|
+
"background:#fff",
|
|
2375
|
+
"transform-origin:bottom " + (f ? "right" : "left"),
|
|
2376
|
+
"transition:opacity .18s,transform .18s",
|
|
2377
|
+
"opacity:0",
|
|
2378
|
+
"transform:scale(.95)"
|
|
2379
|
+
].join(";"), s.el.style.cssText = "width:100%;height:100%;overflow:hidden", g.append(s.el);
|
|
2380
|
+
const C = document.createElement("button");
|
|
2381
|
+
C.style.cssText = [
|
|
2382
|
+
"width:56px;height:56px;border-radius:50%",
|
|
2383
|
+
`background:${s.accent ?? "#4F63F5"}`,
|
|
2384
|
+
"color:#fff;border:none;font-size:24px;cursor:pointer",
|
|
2385
|
+
"box-shadow:0 4px 16px rgba(0,0,0,.25)",
|
|
2386
|
+
"position:relative;flex:none",
|
|
2387
|
+
"transition:transform .15s"
|
|
2388
|
+
].join(";"), C.textContent = "💬", C.onmouseenter = () => {
|
|
2389
|
+
C.style.transform = "scale(1.08)";
|
|
2390
|
+
}, C.onmouseleave = () => {
|
|
2391
|
+
C.style.transform = "scale(1)";
|
|
2392
|
+
}, u = document.createElement("span"), u.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", C.append(u), d.append(g, C), document.body.append(d);
|
|
2393
|
+
const L = (K) => {
|
|
2394
|
+
K ? (g.style.display = "flex", requestAnimationFrame(() => {
|
|
2395
|
+
g.style.opacity = "1", g.style.transform = "scale(1)";
|
|
2396
|
+
})) : (g.style.opacity = "0", g.style.transform = "scale(.95)", setTimeout(() => {
|
|
2397
|
+
y || (g.style.display = "none");
|
|
2398
|
+
}, 180));
|
|
2399
|
+
};
|
|
2400
|
+
C.addEventListener("click", () => {
|
|
2401
|
+
y = !y, L(y), C.textContent = y ? "✕" : "💬", C.append(u), y && (w = 0, u && (u.style.display = "none"));
|
|
2402
|
+
}), document.addEventListener("keydown", (K) => {
|
|
2403
|
+
K.key === "Escape" && y && (y = !1, L(!1), C.textContent = "💬", C.append(u));
|
|
2367
2404
|
});
|
|
2368
2405
|
}
|
|
2369
2406
|
const x = () => {
|
|
2370
|
-
|
|
2371
|
-
},
|
|
2407
|
+
y || (w++, u && (u.textContent = String(w), u.style.display = "flex"));
|
|
2408
|
+
}, p = () => {
|
|
2372
2409
|
try {
|
|
2373
|
-
const l = new AudioContext(),
|
|
2374
|
-
|
|
2410
|
+
const l = new AudioContext(), f = l.createOscillator(), g = l.createGain();
|
|
2411
|
+
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);
|
|
2375
2412
|
} catch {
|
|
2376
2413
|
}
|
|
2377
2414
|
};
|
|
2378
2415
|
let h;
|
|
2379
|
-
const
|
|
2380
|
-
let
|
|
2381
|
-
const
|
|
2382
|
-
let
|
|
2383
|
-
const
|
|
2384
|
-
|
|
2385
|
-
i && h.send({ type: "send", conversationId: i, clientMsgId: l, content:
|
|
2416
|
+
const v = new St(`ocw-e2e-${s.profileId}`);
|
|
2417
|
+
let k = !1;
|
|
2418
|
+
const b = [], E = [];
|
|
2419
|
+
let B = !1;
|
|
2420
|
+
const T = (l, f) => {
|
|
2421
|
+
v.sealText(f).then((g) => {
|
|
2422
|
+
i && h.send({ type: "send", conversationId: i, clientMsgId: l, content: g });
|
|
2386
2423
|
});
|
|
2387
|
-
},
|
|
2388
|
-
|
|
2389
|
-
i && h.send({ type: "send", conversationId: i, clientMsgId: l, content:
|
|
2424
|
+
}, A = (l, f, g) => {
|
|
2425
|
+
v.sealText(f, g).then((C) => {
|
|
2426
|
+
i && h.send({ type: "send", conversationId: i, clientMsgId: l, content: C });
|
|
2390
2427
|
});
|
|
2391
|
-
},
|
|
2392
|
-
for (;
|
|
2393
|
-
const l =
|
|
2394
|
-
|
|
2428
|
+
}, $ = () => {
|
|
2429
|
+
for (; b.length; ) {
|
|
2430
|
+
const l = b.shift();
|
|
2431
|
+
T(l.clientMsgId, l.text);
|
|
2395
2432
|
}
|
|
2396
2433
|
for (; E.length; ) {
|
|
2397
2434
|
const l = E.shift();
|
|
2398
|
-
|
|
2435
|
+
T(l.clientMsgId, l.text);
|
|
2399
2436
|
}
|
|
2400
|
-
},
|
|
2437
|
+
}, _ = (l) => {
|
|
2401
2438
|
h.send({ type: "fetchPrekey", targetUserId: l });
|
|
2402
|
-
},
|
|
2403
|
-
|
|
2404
|
-
const
|
|
2439
|
+
}, D = s.i18n ?? {}, W = ["ar", "he", "fa", "ur"], S = typeof navigator < "u" ? (navigator.language ?? "").slice(0, 2).toLowerCase() : "";
|
|
2440
|
+
W.includes(S) && !s.el.dir && (s.el.dir = "rtl", s.el.style.fontFamily = s.el.style.fontFamily || "Tahoma,Arial,system-ui,sans-serif");
|
|
2441
|
+
const m = new At(s.el, e, {
|
|
2405
2442
|
onSend(l) {
|
|
2406
2443
|
if (!i) return;
|
|
2407
|
-
const
|
|
2408
|
-
t.addOptimistic(
|
|
2444
|
+
const f = `cm_${Math.random().toString(36).slice(2)}`;
|
|
2445
|
+
t.addOptimistic(f, { kind: "text", text: l }), m.render(t), t.e2e ? v.ready ? T(f, l) : B ? E.push({ clientMsgId: f, text: l }) : (b.push({ clientMsgId: f, text: l }), t.assignedAgentId && _(t.assignedAgentId)) : (n.add({ clientMsgId: f, content: { kind: "text", text: l }, ts: Date.now() }), h.send({ type: "send", conversationId: i, clientMsgId: f, content: { kind: "text", text: l } }));
|
|
2409
2446
|
},
|
|
2410
2447
|
async onAttach(l) {
|
|
2411
2448
|
if (!i) return;
|
|
2412
|
-
const
|
|
2413
|
-
t.addOptimistic(
|
|
2449
|
+
const C = `${s.url.replace(/^ws/, "http").replace(/\/ws$/, "")}/upload?name=${encodeURIComponent(l.name)}`, L = `cm_${Math.random().toString(36).slice(2)}`;
|
|
2450
|
+
t.addOptimistic(L, { kind: "text", text: `📎 Uploading ${l.name}…` }), m.render(t);
|
|
2414
2451
|
try {
|
|
2415
|
-
const
|
|
2452
|
+
const K = await fetch(C, {
|
|
2416
2453
|
method: "POST",
|
|
2417
2454
|
headers: { "content-type": l.type, ...s.token ? { authorization: `Bearer ${s.token}` } : {} },
|
|
2418
2455
|
body: l
|
|
2419
2456
|
});
|
|
2420
|
-
if (!
|
|
2421
|
-
const { url: be, name: me, mime: ve, size: ke } = await
|
|
2422
|
-
h.send({ type: "send", conversationId: i, clientMsgId:
|
|
2423
|
-
} catch (
|
|
2424
|
-
t.addOptimistic(
|
|
2457
|
+
if (!K.ok) throw new Error(`Upload failed: ${K.status}`);
|
|
2458
|
+
const { url: be, name: me, mime: ve, size: ke } = await K.json();
|
|
2459
|
+
h.send({ type: "send", conversationId: i, clientMsgId: L, content: { kind: "attachment", url: be, name: me, mime: ve, size: ke } });
|
|
2460
|
+
} catch (K) {
|
|
2461
|
+
t.addOptimistic(L, { kind: "text", text: `⚠️ Upload failed: ${K.message}` }), m.render(t);
|
|
2425
2462
|
}
|
|
2426
2463
|
},
|
|
2427
|
-
onInvoke(l,
|
|
2428
|
-
i && h.send({ type: "invoke", conversationId: i, actionId: l, clientInvokeId: `iv_${Math.random().toString(36).slice(2)}`, ...
|
|
2464
|
+
onInvoke(l, f) {
|
|
2465
|
+
i && h.send({ type: "invoke", conversationId: i, actionId: l, clientInvokeId: `iv_${Math.random().toString(36).slice(2)}`, ...f ? { inputs: f } : {} });
|
|
2429
2466
|
},
|
|
2430
2467
|
onTyping(l) {
|
|
2431
2468
|
i && h.send({ type: "typing", conversationId: i, isTyping: l });
|
|
@@ -2438,19 +2475,19 @@ function $t(s) {
|
|
|
2438
2475
|
const l = t.messages()[0];
|
|
2439
2476
|
l && h.send({ type: "history", conversationId: i, beforeSeq: l.seq, limit: 20 });
|
|
2440
2477
|
},
|
|
2441
|
-
onEdit(l,
|
|
2442
|
-
i && h.send({ type: "edit", conversationId: i, messageId: l, content: { kind: "text", text:
|
|
2478
|
+
onEdit(l, f) {
|
|
2479
|
+
i && h.send({ type: "edit", conversationId: i, messageId: l, content: { kind: "text", text: f } });
|
|
2443
2480
|
},
|
|
2444
2481
|
onDelete(l) {
|
|
2445
2482
|
i && h.send({ type: "delete", conversationId: i, messageId: l });
|
|
2446
2483
|
},
|
|
2447
|
-
onReact(l,
|
|
2448
|
-
i && h.send({ type: "react", conversationId: i, messageId: l, emoji:
|
|
2484
|
+
onReact(l, f, g) {
|
|
2485
|
+
i && h.send({ type: "react", conversationId: i, messageId: l, emoji: f, remove: g });
|
|
2449
2486
|
},
|
|
2450
2487
|
onCsat(l) {
|
|
2451
2488
|
if (!i) return;
|
|
2452
|
-
const
|
|
2453
|
-
fetch(`${
|
|
2489
|
+
const f = s.url.replace(/^ws/, "http").replace(/\/+$/, "").replace(/:\d+$/, (g) => g);
|
|
2490
|
+
fetch(`${f}/conversations/${i}/csat`, {
|
|
2454
2491
|
method: "POST",
|
|
2455
2492
|
headers: { "Content-Type": "application/json", Authorization: `Bearer ${e}` },
|
|
2456
2493
|
body: JSON.stringify({ score: l })
|
|
@@ -2465,16 +2502,16 @@ function $t(s) {
|
|
|
2465
2502
|
},
|
|
2466
2503
|
...s.translateLang ? {
|
|
2467
2504
|
async onTranslate(l) {
|
|
2468
|
-
const
|
|
2505
|
+
const f = s.url.replace(/^ws/, "http").replace(/\/+$/, "");
|
|
2469
2506
|
try {
|
|
2470
|
-
const
|
|
2507
|
+
const g = await fetch(`${f}/translate`, {
|
|
2471
2508
|
method: "POST",
|
|
2472
2509
|
headers: { "content-type": "application/json", authorization: `Bearer ${e}` },
|
|
2473
2510
|
body: JSON.stringify({ text: l, targetLang: s.translateLang })
|
|
2474
2511
|
});
|
|
2475
|
-
if (!
|
|
2476
|
-
const { translated:
|
|
2477
|
-
return
|
|
2512
|
+
if (!g.ok) return null;
|
|
2513
|
+
const { translated: C } = await g.json();
|
|
2514
|
+
return C;
|
|
2478
2515
|
} catch {
|
|
2479
2516
|
return null;
|
|
2480
2517
|
}
|
|
@@ -2484,10 +2521,10 @@ function $t(s) {
|
|
|
2484
2521
|
async onListChats() {
|
|
2485
2522
|
const l = ye(s.url);
|
|
2486
2523
|
try {
|
|
2487
|
-
const
|
|
2524
|
+
const f = await fetch(`${l}/conversations/mine?profileId=${encodeURIComponent(s.profileId)}`, {
|
|
2488
2525
|
headers: { authorization: `Bearer ${e}` }
|
|
2489
2526
|
});
|
|
2490
|
-
return
|
|
2527
|
+
return f.ok ? (await f.json()).conversations ?? [] : [];
|
|
2491
2528
|
} catch {
|
|
2492
2529
|
return [];
|
|
2493
2530
|
}
|
|
@@ -2495,9 +2532,9 @@ function $t(s) {
|
|
|
2495
2532
|
onSwitchChat(l) {
|
|
2496
2533
|
if (!l.id || l.id === "__new__") return;
|
|
2497
2534
|
r == null || r.close(), s.el.replaceChildren();
|
|
2498
|
-
const { subjectId:
|
|
2535
|
+
const { subjectId: f, token: g, ...C } = s;
|
|
2499
2536
|
r = $t({
|
|
2500
|
-
...
|
|
2537
|
+
...C,
|
|
2501
2538
|
token: e,
|
|
2502
2539
|
// always the resolved identity, never undefined
|
|
2503
2540
|
...l.subjectId ? { subjectId: l.subjectId } : {},
|
|
@@ -2509,9 +2546,11 @@ function $t(s) {
|
|
|
2509
2546
|
...s.subject ? { subject: s.subject } : {},
|
|
2510
2547
|
...s.quickReplies ? { quickReplies: s.quickReplies } : {},
|
|
2511
2548
|
...s.accent ? { accent: s.accent } : {},
|
|
2512
|
-
...(
|
|
2513
|
-
i18n:
|
|
2514
|
-
|
|
2549
|
+
...(P = s.user) != null && P.name || (R = s.user) != null && R.avatar ? { userInfo: { ...s.user.name ? { name: s.user.name } : {}, ...s.user.avatar ? { avatar: s.user.avatar } : {} } } : {},
|
|
2550
|
+
i18n: D,
|
|
2551
|
+
// Start directly on chat screen when a specific conversation is known upfront
|
|
2552
|
+
...s.showChatList && s.subjectId ? { startOnChat: !0 } : {}
|
|
2553
|
+
}), q = {
|
|
2515
2554
|
type: "open",
|
|
2516
2555
|
profileId: s.profileId,
|
|
2517
2556
|
...s.subjectId ? { subjectId: s.subjectId } : {},
|
|
@@ -2519,74 +2558,76 @@ function $t(s) {
|
|
|
2519
2558
|
// This is pure display metadata — it never affects identity or access.
|
|
2520
2559
|
...typeof location < "u" ? { pageUrl: location.href } : {},
|
|
2521
2560
|
...typeof document < "u" && document.title ? { pageTitle: document.title } : {}
|
|
2522
|
-
},
|
|
2523
|
-
const
|
|
2524
|
-
if (!
|
|
2525
|
-
const
|
|
2526
|
-
if (
|
|
2561
|
+
}, V = (l) => {
|
|
2562
|
+
const f = s.user;
|
|
2563
|
+
if (!f || !f.name && !f.email && !f.avatar && !f.meta) return;
|
|
2564
|
+
const g = [];
|
|
2565
|
+
if (f.name && g.push(`Name: ${f.name}`), f.email && g.push(`Email: ${f.email}`), f.avatar && g.push(`Avatar: ${f.avatar}`), f.meta) for (const [C, L] of Object.entries(f.meta)) g.push(`${C}: ${L}`);
|
|
2527
2566
|
h.send({ type: "note", conversationId: l, clientMsgId: `ui_${Date.now()}`, text: `[User info]
|
|
2528
|
-
${
|
|
2567
|
+
${g.join(`
|
|
2529
2568
|
`)}` });
|
|
2530
2569
|
};
|
|
2531
2570
|
return h = new lt({
|
|
2532
2571
|
url: s.url,
|
|
2533
2572
|
token: e,
|
|
2534
|
-
open:
|
|
2573
|
+
open: q,
|
|
2535
2574
|
getCursor: () => t.highestSeq(),
|
|
2536
|
-
onStatusChange: (l) =>
|
|
2575
|
+
onStatusChange: (l) => m.setConnStatus(l),
|
|
2537
2576
|
onFrame(l) {
|
|
2538
2577
|
if (l.type === "opened") {
|
|
2539
|
-
const
|
|
2578
|
+
const f = i === void 0;
|
|
2540
2579
|
if (i = l.conversation.id, !o) {
|
|
2541
2580
|
o = !0;
|
|
2542
|
-
for (const
|
|
2543
|
-
h.send({ type: "send", conversationId: i, clientMsgId:
|
|
2581
|
+
for (const g of n.load())
|
|
2582
|
+
h.send({ type: "send", conversationId: i, clientMsgId: g.clientMsgId, content: g.content });
|
|
2544
2583
|
}
|
|
2545
|
-
|
|
2584
|
+
f && (zt(s.url, e, i, t, m), l.conversation.lastSeq === 0 && V(i), s.showChatList && s.subjectId && m.showChatScreen());
|
|
2546
2585
|
}
|
|
2547
2586
|
if (l.type === "ack" && n.remove(l.clientMsgId), l.type === "prekeyBundle") {
|
|
2548
|
-
l.bundle && (
|
|
2549
|
-
const
|
|
2550
|
-
for (const
|
|
2551
|
-
|
|
2587
|
+
l.bundle && (B = !0, v.x3dhSendTo(l.bundle).then((f) => {
|
|
2588
|
+
const g = [...b.splice(0), ...E.splice(0)];
|
|
2589
|
+
for (const C of g) A(C.clientMsgId, C.text, f);
|
|
2590
|
+
m.render(t);
|
|
2552
2591
|
}));
|
|
2553
2592
|
return;
|
|
2554
2593
|
}
|
|
2555
2594
|
if (l.type === "message" && t.e2e) {
|
|
2556
|
-
const
|
|
2557
|
-
if (
|
|
2558
|
-
|
|
2559
|
-
await
|
|
2595
|
+
const f = Ct(l.message.content);
|
|
2596
|
+
if (f && !v.ready) {
|
|
2597
|
+
v.x3dhReceiveFrom(f.x3dhIK, f.x3dhEK, f.x3dhSPK).then(async () => {
|
|
2598
|
+
await v.openFrame(l), t.apply(l), m.render(t);
|
|
2560
2599
|
});
|
|
2561
2600
|
return;
|
|
2562
2601
|
}
|
|
2563
2602
|
}
|
|
2564
2603
|
if (l.type === "peerkey") {
|
|
2565
|
-
|
|
2566
|
-
|
|
2604
|
+
v.onPeerKey(l.key).then(() => {
|
|
2605
|
+
$(), m.render(t);
|
|
2567
2606
|
});
|
|
2568
2607
|
return;
|
|
2569
2608
|
}
|
|
2570
2609
|
(async () => {
|
|
2571
|
-
if (t.e2e && await
|
|
2572
|
-
|
|
2573
|
-
const
|
|
2574
|
-
h.send({ type: "uploadPrekeys", ...
|
|
2575
|
-
const
|
|
2576
|
-
h.send({ type: "pubkey", conversationId: i, key:
|
|
2610
|
+
if (t.e2e && await v.openFrame(l), t.apply(l), l.type === "message" && l.message.senderId !== e && !l.message.internal && (s.showChatList && m.isInChatScreen() || x(), p()), t.e2e && i && !k) {
|
|
2611
|
+
k = !0;
|
|
2612
|
+
const f = await v.initX3DH();
|
|
2613
|
+
h.send({ type: "uploadPrekeys", ...f });
|
|
2614
|
+
const g = await v.begin();
|
|
2615
|
+
h.send({ type: "pubkey", conversationId: i, key: g });
|
|
2577
2616
|
}
|
|
2578
|
-
|
|
2617
|
+
m.render(t), i && m.setSeenSeq(i, t.highestSeq());
|
|
2579
2618
|
})();
|
|
2580
2619
|
}
|
|
2581
|
-
}), s.showChatList &&
|
|
2582
|
-
|
|
2583
|
-
} }, r
|
|
2620
|
+
}), s.showChatList && m.initSeenSeq(`${s.profileId}_${e.slice(-8)}`), s.showChatList && !s.subjectId ? (r = { close: () => {
|
|
2621
|
+
d == null || d.remove(), m.destroy();
|
|
2622
|
+
} }, r) : (h.connect(), m.render(t), r = { close: () => {
|
|
2623
|
+
h.close(), d == null || d.remove(), m.destroy();
|
|
2624
|
+
} }, r);
|
|
2584
2625
|
}
|
|
2585
2626
|
export {
|
|
2586
2627
|
dt as ChatStore,
|
|
2587
2628
|
lt as ConnectionManager,
|
|
2588
2629
|
St as E2ESession,
|
|
2589
|
-
|
|
2630
|
+
ft as PersistentOutbox,
|
|
2590
2631
|
At as Renderer,
|
|
2591
2632
|
Dt as asConversationId,
|
|
2592
2633
|
Ct as extractX3DHInit,
|