@mrrocket/sdk 0.22.0 → 0.23.0
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/CHANGELOG.md +8 -0
- package/dist/api-client.d.ts +14 -1
- package/dist/api-client.js +13 -4
- package/dist/api-client.js.map +1 -1
- package/dist/browser/mrrocket-flows.js +2 -2
- package/dist/browser/mrrocket-messenger.js +14 -5
- package/dist/browser/mrrocket.js +1 -1
- package/dist/client.js +7 -2
- package/dist/client.js.map +1 -1
- package/dist/core.d.ts +3 -1
- package/dist/core.js +3 -1
- package/dist/core.js.map +1 -1
- package/dist/messenger-ui.d.ts +2 -0
- package/dist/messenger-ui.js +138 -25
- package/dist/messenger-ui.js.map +1 -1
- package/dist/messenger.js +1 -0
- package/dist/messenger.js.map +1 -1
- package/dist/react-native/index.d.cts +5 -2
- package/dist/react-native/index.d.ts +5 -2
- package/dist/react-native/index.js +18 -8
- package/dist/react-native/index.js.map +1 -1
- package/dist/styles-css.d.ts +1 -1
- package/dist/styles-css.js +11 -2
- package/dist/styles-css.js.map +1 -1
- package/package.json +1 -1
package/dist/messenger-ui.js
CHANGED
|
@@ -6,12 +6,14 @@ import {
|
|
|
6
6
|
CHAT_FILE_TYPES,
|
|
7
7
|
createApi,
|
|
8
8
|
inkOn,
|
|
9
|
-
replyLine
|
|
9
|
+
replyLine,
|
|
10
|
+
stillThere
|
|
10
11
|
} from "./api-client.js";
|
|
11
12
|
import { currentLocale, onWords, t, tf, wordsLang, wordsVersion } from "./i18n.js";
|
|
12
13
|
import { injectStyles } from "./styles-css.js";
|
|
13
14
|
var UPDATES_SHOWN = 20;
|
|
14
15
|
var POLL_OPEN_MS = 4e3;
|
|
16
|
+
var READ_PATIENCE_MS = 5e3;
|
|
15
17
|
var POLL_WAITING_MS = 8e3;
|
|
16
18
|
var POLL_IDLE_MS = 3e4;
|
|
17
19
|
var POLL_QUIET_MS = 6e4;
|
|
@@ -188,6 +190,23 @@ var writeCachedLook = (apiKey, look) => {
|
|
|
188
190
|
} catch {
|
|
189
191
|
}
|
|
190
192
|
};
|
|
193
|
+
var CHATS_KEY = "ckw_msgr_chats:";
|
|
194
|
+
var PRODUCT_KEY = "ckw_msgr_product:";
|
|
195
|
+
var KEPT = 20;
|
|
196
|
+
var kept = (key) => {
|
|
197
|
+
try {
|
|
198
|
+
return JSON.parse(window.localStorage.getItem(key) ?? "null");
|
|
199
|
+
} catch {
|
|
200
|
+
return null;
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
var keep = (key, value) => {
|
|
204
|
+
try {
|
|
205
|
+
if (value) window.localStorage.setItem(key, JSON.stringify(value));
|
|
206
|
+
else window.localStorage.removeItem(key);
|
|
207
|
+
} catch {
|
|
208
|
+
}
|
|
209
|
+
};
|
|
191
210
|
var mountMessenger = (o) => {
|
|
192
211
|
let real = null;
|
|
193
212
|
let shown = "";
|
|
@@ -233,6 +252,7 @@ var mountMessenger = (o) => {
|
|
|
233
252
|
open: (v) => later((h) => h.open(v)),
|
|
234
253
|
close: () => real?.close(),
|
|
235
254
|
toggle: () => later((h) => h.toggle()),
|
|
255
|
+
refresh: () => real?.refresh(),
|
|
236
256
|
destroy: () => {
|
|
237
257
|
gone = true;
|
|
238
258
|
offWords();
|
|
@@ -252,7 +272,7 @@ var build = (o) => {
|
|
|
252
272
|
const label = o.label ?? "";
|
|
253
273
|
const reply = replyLine(o.replyTime);
|
|
254
274
|
const initial = (title.trim()[0] ?? "?").toUpperCase();
|
|
255
|
-
const whoLabel = { visitor: t("You"), team: t("Team"), ai: o.agentName?.trim()
|
|
275
|
+
const whoLabel = { visitor: t("You"), team: t("Team"), ai: o.agentName?.trim() ? `${o.agentName.trim()} \xB7 ${t("AI agent")}` : t("AI agent"), auto: t("Team") };
|
|
256
276
|
const launcherOn = o.launcher ?? true;
|
|
257
277
|
const helpOn = o.help ?? true;
|
|
258
278
|
const updatesOn = o.updates ?? true;
|
|
@@ -302,10 +322,40 @@ var build = (o) => {
|
|
|
302
322
|
let query = "";
|
|
303
323
|
let rated = /* @__PURE__ */ new Set();
|
|
304
324
|
let hasArticles = null;
|
|
325
|
+
let homeArticles = [];
|
|
326
|
+
let misses = 0;
|
|
305
327
|
let updates = null;
|
|
328
|
+
let hasUpdates = false;
|
|
306
329
|
let updatesNode = null;
|
|
307
330
|
let collection = null;
|
|
308
331
|
let wide = false;
|
|
332
|
+
const remembers = !o.client && !!o.apiKey;
|
|
333
|
+
const chatsKey = CHATS_KEY + o.apiKey;
|
|
334
|
+
const productKey = PRODUCT_KEY + o.apiKey;
|
|
335
|
+
let visitor = o.distinctId();
|
|
336
|
+
let person = o.user()?.id;
|
|
337
|
+
const recall = () => {
|
|
338
|
+
const m = remembers ? kept(chatsKey) : null;
|
|
339
|
+
chats = m?.who === visitor && Array.isArray(m.chats) ? m.chats : [];
|
|
340
|
+
};
|
|
341
|
+
recall();
|
|
342
|
+
if (remembers) {
|
|
343
|
+
const m = kept(productKey);
|
|
344
|
+
if (m?.articles?.length) {
|
|
345
|
+
homeArticles = m.articles;
|
|
346
|
+
articles = m.articles;
|
|
347
|
+
hasArticles = true;
|
|
348
|
+
}
|
|
349
|
+
hasUpdates = !!m?.updates;
|
|
350
|
+
}
|
|
351
|
+
const rememberChats = (who) => {
|
|
352
|
+
if (!remembers || o.distinctId() !== who) return;
|
|
353
|
+
if (chats.length) keep(chatsKey, { who, chats: chats.slice(0, KEPT) });
|
|
354
|
+
else if (kept(chatsKey)?.who === who) keep(chatsKey, null);
|
|
355
|
+
};
|
|
356
|
+
const rememberProduct = () => {
|
|
357
|
+
if (remembers) keep(productKey, homeArticles.length || hasUpdates ? { articles: homeArticles.slice(0, KEPT), updates: hasUpdates } : null);
|
|
358
|
+
};
|
|
309
359
|
const isAnswer = (m) => m.from === "team" || m.from === "ai";
|
|
310
360
|
const watching = () => open && view === "messages" && document.visibilityState !== "hidden";
|
|
311
361
|
const shownChat = () => listing || draft !== null ? null : chatId ?? thread?.conversation?.id ?? null;
|
|
@@ -342,6 +392,7 @@ var build = (o) => {
|
|
|
342
392
|
if (c.id !== read?.id) learn(c.id, c.last && isAnswer(c.last) ? [c.last] : [], c.last?.at, c.status === "solved" && i > 0);
|
|
343
393
|
});
|
|
344
394
|
if (read) learn(read.id, t2.messages.filter(isAnswer), last?.at, read.status === "solved" && chats[0]?.id !== read.id);
|
|
395
|
+
unseen = unseen.filter(stillThere(t2, chats));
|
|
345
396
|
if (chatId === null || read?.id === chatId) thread = t2;
|
|
346
397
|
if (watching()) markSeen();
|
|
347
398
|
};
|
|
@@ -351,8 +402,8 @@ var build = (o) => {
|
|
|
351
402
|
unseen = unseen.filter((m) => m.chat !== chat);
|
|
352
403
|
const at = known.get(chat);
|
|
353
404
|
if (!at || seen.chats[chat] === at) return;
|
|
354
|
-
const
|
|
355
|
-
seen = { ...seen, chats: { ...
|
|
405
|
+
const kept2 = Object.fromEntries(Object.entries(seen.chats).filter(([c]) => chats.some((x) => x.id === c)));
|
|
406
|
+
seen = { ...seen, chats: { ...kept2, [chat]: at } };
|
|
356
407
|
writeSeen(seen.chats);
|
|
357
408
|
};
|
|
358
409
|
const enterChat = (id, d, list2 = false) => {
|
|
@@ -555,7 +606,7 @@ var build = (o) => {
|
|
|
555
606
|
else if (view === "help") mid.replaceChildren(el("b", {}, t("Help")));
|
|
556
607
|
else if (view === "updates") mid.replaceChildren(el("b", {}, t("Updates")));
|
|
557
608
|
else mid.replaceChildren();
|
|
558
|
-
const items = [homeTab, chatTab, ...helpOn && hasArticles
|
|
609
|
+
const items = [homeTab, chatTab, ...helpOn && hasArticles ? [helpTab] : [], ...updatesOn && (updates ? updates.length : hasUpdates) ? [updatesTab] : []];
|
|
559
610
|
if (tabs.childNodes.length !== items.length || items.some((t2, i) => tabs.childNodes[i] !== t2)) tabs.replaceChildren(...items);
|
|
560
611
|
tabs.toggleAttribute("data-four", items.length > 3);
|
|
561
612
|
homeTab.setAttribute("aria-current", view === "home" ? "page" : "false");
|
|
@@ -827,7 +878,11 @@ var build = (o) => {
|
|
|
827
878
|
const r = await api().articles(q || void 0);
|
|
828
879
|
if (q !== query.trim()) return;
|
|
829
880
|
articles = r.articles;
|
|
830
|
-
if (!q)
|
|
881
|
+
if (!q) {
|
|
882
|
+
homeArticles = r.articles;
|
|
883
|
+
hasArticles = r.articles.length > 0;
|
|
884
|
+
rememberProduct();
|
|
885
|
+
}
|
|
831
886
|
} catch {
|
|
832
887
|
articles = articles ?? [];
|
|
833
888
|
} finally {
|
|
@@ -838,6 +893,8 @@ var build = (o) => {
|
|
|
838
893
|
const loadUpdates = async () => {
|
|
839
894
|
try {
|
|
840
895
|
updates = (await api().changelog()).entries.slice(0, UPDATES_SHOWN);
|
|
896
|
+
hasUpdates = updates.length > 0;
|
|
897
|
+
rememberProduct();
|
|
841
898
|
} catch {
|
|
842
899
|
updates = [];
|
|
843
900
|
}
|
|
@@ -862,6 +919,25 @@ var build = (o) => {
|
|
|
862
919
|
go("messages");
|
|
863
920
|
if (canSend()) submit();
|
|
864
921
|
});
|
|
922
|
+
const shapes = (rows, card = false) => el(
|
|
923
|
+
"div",
|
|
924
|
+
{ class: "ckw-msgr-shapes", "aria-hidden": "true" },
|
|
925
|
+
...Array.from(
|
|
926
|
+
{ length: rows },
|
|
927
|
+
() => el(
|
|
928
|
+
"div",
|
|
929
|
+
{ class: card ? "ckw-msgr-card ckw-msgr-recent" : "ckw-msgr-shape" },
|
|
930
|
+
el("span", { class: "ckw-msgr-recent-row" }, card ? el("span", { class: "ckw-msgr-av ckw-msgr-av-sm ckw-msgr-sk" }) : null, el("span", { class: "ckw-msgr-card-main" }, el("span", { class: "ckw-msgr-sk" }), el("span", { class: "ckw-msgr-sk" })))
|
|
931
|
+
)
|
|
932
|
+
)
|
|
933
|
+
);
|
|
934
|
+
const still = (node) => {
|
|
935
|
+
if (node.isConnected) node.setAttribute("data-still", "");
|
|
936
|
+
return node;
|
|
937
|
+
};
|
|
938
|
+
const chatShape = shapes(1, true);
|
|
939
|
+
const listShape = shapes(3);
|
|
940
|
+
let homeSeen = null;
|
|
865
941
|
const chatRow = (c) => {
|
|
866
942
|
const m = c.last;
|
|
867
943
|
const n = unseenIn(c.id);
|
|
@@ -911,9 +987,16 @@ var build = (o) => {
|
|
|
911
987
|
el("span", { class: "ckw-msgr-hello-sub" }, rest)
|
|
912
988
|
);
|
|
913
989
|
const parts = [hero, askForm];
|
|
990
|
+
const shown = /* @__PURE__ */ new Set();
|
|
991
|
+
const arriving = (node, key) => {
|
|
992
|
+
shown.add(key);
|
|
993
|
+
if (homeSeen && !homeSeen.has(key)) node.setAttribute("data-arrive", "");
|
|
994
|
+
return node;
|
|
995
|
+
};
|
|
914
996
|
const running = chats.filter((c) => c.status !== "solved");
|
|
915
997
|
const rows = (running.length ? running : chats).slice(0, 2);
|
|
916
|
-
parts.push(...rows.map(chatRow));
|
|
998
|
+
parts.push(...rows.map((c) => arriving(chatRow(c), c.id)));
|
|
999
|
+
if (!rows.length && !loaded && misses < 3 && o.user()?.id) parts.push(still(chatShape));
|
|
917
1000
|
if (chats.length > rows.length) {
|
|
918
1001
|
const all = el("button", { type: "button", class: "ckw-msgr-all" }, tf("All conversations ({n})", { n: chats.length }), icon(I.next, 14));
|
|
919
1002
|
all.addEventListener("click", () => {
|
|
@@ -922,13 +1005,9 @@ var build = (o) => {
|
|
|
922
1005
|
});
|
|
923
1006
|
parts.push(all);
|
|
924
1007
|
}
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
if (top.length) helpCard.append(...top.map(articleRow));
|
|
929
|
-
else if (articles === null) helpCard.append(el("div", { class: "ckw-skel ckw-msgr-skel" }));
|
|
930
|
-
parts.push(helpCard);
|
|
931
|
-
}
|
|
1008
|
+
const top = helpOn ? homeArticles.slice(0, 3) : [];
|
|
1009
|
+
if (top.length) parts.push(arriving(el("div", { class: "ckw-msgr-card ckw-msgr-card-col" }, ...top.map(articleRow)), "help"));
|
|
1010
|
+
homeSeen = shown;
|
|
932
1011
|
body.replaceChildren(...parts);
|
|
933
1012
|
};
|
|
934
1013
|
const drawHelp = () => {
|
|
@@ -940,7 +1019,7 @@ var build = (o) => {
|
|
|
940
1019
|
const inside = !q && collection !== null ? groups.get(collection) ?? [] : null;
|
|
941
1020
|
const heading = q ? t("Search results") : inside ? collection ?? "" : t("Most read articles");
|
|
942
1021
|
const parts = [el("h2", { class: "ckw-msgr-help-h" }, heading), helpSearch];
|
|
943
|
-
if (articles === null) parts.push(
|
|
1022
|
+
if (articles === null) parts.push(still(listShape));
|
|
944
1023
|
else if (!all.length) {
|
|
945
1024
|
const ask = el("button", { type: "button", class: "ckw-btn ckw-btn-primary" }, t("Send us a message"));
|
|
946
1025
|
ask.addEventListener("click", askAnew);
|
|
@@ -975,7 +1054,7 @@ var build = (o) => {
|
|
|
975
1054
|
}
|
|
976
1055
|
};
|
|
977
1056
|
const drawUpdates = () => {
|
|
978
|
-
updatesNode ??= !updates ?
|
|
1057
|
+
updatesNode ??= !updates ? shapes(3) : !updates.length ? el("div", { class: "ckw-msgr-empty" }, el("p", {}, t("No updates yet."))) : el(
|
|
979
1058
|
"div",
|
|
980
1059
|
{ class: "ckw-msgr-updates" },
|
|
981
1060
|
...updates.map((e) => el("article", { class: "ckw-msgr-update" }, el("p", { class: "ckw-msgr-doc-c" }, timeAgo(e.publishedAt)), el("h2", { class: "ckw-msgr-update-t" }, e.title), e.body ? el("p", { class: "ckw-msgr-update-b" }, e.body) : null))
|
|
@@ -985,7 +1064,7 @@ var build = (o) => {
|
|
|
985
1064
|
let articleShown = null;
|
|
986
1065
|
const drawArticle = (id) => {
|
|
987
1066
|
if (articleShown?.id === id) return body.replaceChildren(articleShown.node);
|
|
988
|
-
const node = el("article", { class: "ckw-msgr-doc" },
|
|
1067
|
+
const node = el("article", { class: "ckw-msgr-doc" }, shapes(4));
|
|
989
1068
|
articleShown = { id, node };
|
|
990
1069
|
body.replaceChildren(node);
|
|
991
1070
|
api().article(id).then((a) => {
|
|
@@ -1091,27 +1170,59 @@ var build = (o) => {
|
|
|
1091
1170
|
const tick = async () => {
|
|
1092
1171
|
if (ctrl) return;
|
|
1093
1172
|
const mine = ctrl = new AbortController();
|
|
1173
|
+
const asked = o.distinctId();
|
|
1174
|
+
let late = false;
|
|
1175
|
+
const patience = setTimeout(() => {
|
|
1176
|
+
late = true;
|
|
1177
|
+
mine.abort();
|
|
1178
|
+
}, Math.min(READ_PATIENCE_MS * 2 ** misses, POLL_IDLE_MS));
|
|
1179
|
+
let again;
|
|
1094
1180
|
try {
|
|
1095
1181
|
take(await api().chat(mine.signal, chatId ?? void 0));
|
|
1096
1182
|
error = "";
|
|
1097
1183
|
refused = false;
|
|
1184
|
+
misses = 0;
|
|
1185
|
+
rememberChats(asked);
|
|
1098
1186
|
} catch (e) {
|
|
1099
|
-
if (e.name === "AbortError") return;
|
|
1187
|
+
if (e.name === "AbortError" && !late) return;
|
|
1100
1188
|
const status = e.status;
|
|
1101
1189
|
refused = status === 401 || status === 403;
|
|
1102
1190
|
if (status === 404 && chatId) enterMessages();
|
|
1103
|
-
else if (open && view === "messages") error = sayable(e);
|
|
1191
|
+
else if (open && view === "messages" && !late) error = sayable(e);
|
|
1192
|
+
if (late || status === void 0 || status >= 500) {
|
|
1193
|
+
misses += 1;
|
|
1194
|
+
again = late ? 0 : Math.min(1e3 * 2 ** (misses - 1), POLL_IDLE_MS);
|
|
1195
|
+
}
|
|
1104
1196
|
} finally {
|
|
1197
|
+
clearTimeout(patience);
|
|
1105
1198
|
if (ctrl === mine) ctrl = null;
|
|
1106
1199
|
}
|
|
1107
|
-
if (!loaded) {
|
|
1200
|
+
if (!loaded && again === void 0) {
|
|
1108
1201
|
listCount = -1;
|
|
1109
1202
|
if (view === "messages" && chatId === null && draft === null && !text.value.trim() && !outbox.length && !picked.length) enterMessages();
|
|
1203
|
+
loaded = true;
|
|
1110
1204
|
}
|
|
1111
|
-
loaded = true;
|
|
1112
1205
|
draw();
|
|
1113
1206
|
drawFab();
|
|
1114
|
-
schedule();
|
|
1207
|
+
schedule(open && document.visibilityState !== "hidden" ? again : void 0);
|
|
1208
|
+
};
|
|
1209
|
+
const refresh = () => {
|
|
1210
|
+
const who = o.distinctId();
|
|
1211
|
+
if (who === visitor && !refused) return;
|
|
1212
|
+
if (who !== visitor) {
|
|
1213
|
+
if (person && !o.user()?.id && remembers) keep(chatsKey, null);
|
|
1214
|
+
visitor = who;
|
|
1215
|
+
ctrl?.abort();
|
|
1216
|
+
ctrl = null;
|
|
1217
|
+
unseen = [];
|
|
1218
|
+
loaded = false;
|
|
1219
|
+
misses = 0;
|
|
1220
|
+
recall();
|
|
1221
|
+
}
|
|
1222
|
+
person = o.user()?.id;
|
|
1223
|
+
draw();
|
|
1224
|
+
drawFab();
|
|
1225
|
+
schedule(0);
|
|
1115
1226
|
};
|
|
1116
1227
|
function schedule(now) {
|
|
1117
1228
|
clearTimeout(poll);
|
|
@@ -1239,16 +1350,17 @@ var build = (o) => {
|
|
|
1239
1350
|
addFiles([...e.dataTransfer?.files ?? []]);
|
|
1240
1351
|
});
|
|
1241
1352
|
email.addEventListener("input", () => draw());
|
|
1242
|
-
function show(v = "home",
|
|
1353
|
+
function show(v = "home", still2 = false) {
|
|
1243
1354
|
const was = open;
|
|
1244
1355
|
open = true;
|
|
1245
1356
|
view = v === "help" && !helpOn || v === "updates" && !updatesOn ? "home" : v;
|
|
1246
1357
|
drawn = -1;
|
|
1247
1358
|
previewGone = true;
|
|
1248
|
-
|
|
1359
|
+
homeSeen = null;
|
|
1360
|
+
pop.toggleAttribute("data-still", still2);
|
|
1249
1361
|
enter(pop);
|
|
1250
1362
|
if (was) replay(body, "ckw-msgr-enter");
|
|
1251
|
-
if (articles === null || view === "help" && query) void loadArticles();
|
|
1363
|
+
if (articles === null || hasArticles === null || view === "help" && query) void loadArticles();
|
|
1252
1364
|
draw();
|
|
1253
1365
|
drawFab();
|
|
1254
1366
|
if (view === "messages") {
|
|
@@ -1293,6 +1405,7 @@ var build = (o) => {
|
|
|
1293
1405
|
},
|
|
1294
1406
|
close,
|
|
1295
1407
|
toggle: () => open ? close() : show(),
|
|
1408
|
+
refresh,
|
|
1296
1409
|
isOpen: () => open,
|
|
1297
1410
|
onClose: (fn) => {
|
|
1298
1411
|
afterClose = fn;
|