@ripperts/poco-agent-embed 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/index.js +88 -28
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -120,4 +120,4 @@ export function AgentChat({ getAccessToken }: AgentChatProps) {
|
|
|
120
120
|
|
|
121
121
|
支持现代 Chrome、Edge、Firefox 和 Safari。Vue 2 项目可以正常接入,但不支持 Internet Explorer 11。
|
|
122
122
|
|
|
123
|
-
完整参数和安全配置请参阅 [Agent 外部嵌入文档](https://ai-agent.fsxgt.cn/docs/
|
|
123
|
+
完整参数和安全配置请参阅 [Agent 外部嵌入文档](https://ai-agent.fsxgt.cn/docs/getting-started/agent-embed)。
|
package/index.js
CHANGED
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
var MESSAGE_REQUEST_AUTH = "poco-agent-embed:request-auth";
|
|
19
19
|
var MESSAGE_AUTHENTICATE = "poco-agent-embed:authenticate";
|
|
20
20
|
var MESSAGE_ERROR = "poco-agent-embed:error";
|
|
21
|
+
var MESSAGE_DRAG = "poco-agent-embed:drag";
|
|
21
22
|
|
|
22
23
|
function trimTrailingSlash(value) {
|
|
23
24
|
return String(value || "").replace(/\/+$/, "");
|
|
@@ -106,10 +107,15 @@
|
|
|
106
107
|
var language = ["en", "zh"].includes(requestedLanguage)
|
|
107
108
|
? requestedLanguage
|
|
108
109
|
: "en";
|
|
110
|
+
var toggleButtonLabels =
|
|
111
|
+
language === "zh"
|
|
112
|
+
? { open: "打开 AI 助手", close: "关闭 AI 助手" }
|
|
113
|
+
: { open: "Open AI Agent", close: "Close AI Agent" };
|
|
109
114
|
var theme = ["light", "dark", "system"].includes(options.theme)
|
|
110
115
|
? options.theme
|
|
111
116
|
: "system";
|
|
112
117
|
var query = new URLSearchParams({ channel: channel, theme: theme });
|
|
118
|
+
if (!target && options.draggable !== false) query.set("draggable", "1");
|
|
113
119
|
var iframe = document.createElement("iframe");
|
|
114
120
|
iframe.src =
|
|
115
121
|
baseUrl +
|
|
@@ -133,9 +139,26 @@
|
|
|
133
139
|
var container = document.createElement("div");
|
|
134
140
|
var button = null;
|
|
135
141
|
var updateViewportPosition = null;
|
|
142
|
+
var handleFrameDrag = null;
|
|
136
143
|
var openIcon = createIcon(options.openIcon, false);
|
|
137
144
|
var closeIcon = createIcon(options.closeIcon, true);
|
|
138
145
|
|
|
146
|
+
function renderFloatingState() {
|
|
147
|
+
container.style.opacity = opened ? "1" : "0";
|
|
148
|
+
container.style.visibility = opened ? "visible" : "hidden";
|
|
149
|
+
container.style.pointerEvents = opened ? "auto" : "none";
|
|
150
|
+
container.style.transform = opened ? "scale(1)" : "scale(.96)";
|
|
151
|
+
if (!button) return;
|
|
152
|
+
button.replaceChildren(opened ? closeIcon : openIcon);
|
|
153
|
+
button.setAttribute("aria-expanded", opened ? "true" : "false");
|
|
154
|
+
button.setAttribute(
|
|
155
|
+
"aria-label",
|
|
156
|
+
opened
|
|
157
|
+
? toggleButtonLabels.close
|
|
158
|
+
: options.ariaLabel || toggleButtonLabels.open,
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
|
|
139
162
|
if (target) {
|
|
140
163
|
container.style.cssText =
|
|
141
164
|
"position:relative;width:100%;height:100%;overflow:hidden";
|
|
@@ -145,8 +168,6 @@
|
|
|
145
168
|
container.style.cssText = [
|
|
146
169
|
"position:fixed",
|
|
147
170
|
"width:min(420px,calc(100vw - 24px))",
|
|
148
|
-
"height:min(720px,calc(100dvh - 96px))",
|
|
149
|
-
"min-height:min(360px,calc(100dvh - 96px))",
|
|
150
171
|
"overflow:hidden",
|
|
151
172
|
"border:1px solid color-mix(in srgb,CanvasText 25%,transparent)",
|
|
152
173
|
"border-radius:16px",
|
|
@@ -160,7 +181,6 @@
|
|
|
160
181
|
|
|
161
182
|
button = document.createElement("button");
|
|
162
183
|
button.type = "button";
|
|
163
|
-
button.setAttribute("aria-label", options.ariaLabel || "Open AI Agent");
|
|
164
184
|
button.style.cssText = [
|
|
165
185
|
"position:fixed",
|
|
166
186
|
"display:flex",
|
|
@@ -182,25 +202,17 @@
|
|
|
182
202
|
var position = options.position || "bottom-right";
|
|
183
203
|
var vertical = position.indexOf("top") === 0 ? "top" : "bottom";
|
|
184
204
|
var horizontal = position.indexOf("left") > -1 ? "left" : "right";
|
|
185
|
-
|
|
205
|
+
var verticalOffset = vertical === "bottom" ? 100 : 20;
|
|
206
|
+
var popupAvailableHeight =
|
|
207
|
+
"calc(100dvh - " + (verticalOffset + 76) + "px)";
|
|
208
|
+
button.style[vertical] = verticalOffset + "px";
|
|
186
209
|
button.style[horizontal] = "20px";
|
|
187
|
-
container.style[vertical] = "
|
|
210
|
+
container.style[vertical] = verticalOffset + 64 + "px";
|
|
188
211
|
container.style[horizontal] = "20px";
|
|
212
|
+
container.style.height = "min(720px," + popupAvailableHeight + ")";
|
|
213
|
+
container.style.minHeight = "min(360px," + popupAvailableHeight + ")";
|
|
189
214
|
container.style.transformOrigin = vertical + " " + horizontal;
|
|
190
215
|
|
|
191
|
-
function renderButtonIcon() {
|
|
192
|
-
button.replaceChildren(opened ? closeIcon : openIcon);
|
|
193
|
-
button.setAttribute("aria-expanded", opened ? "true" : "false");
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
function renderOpenState() {
|
|
197
|
-
container.style.opacity = opened ? "1" : "0";
|
|
198
|
-
container.style.visibility = opened ? "visible" : "hidden";
|
|
199
|
-
container.style.pointerEvents = opened ? "auto" : "none";
|
|
200
|
-
container.style.transform = opened ? "scale(1)" : "scale(.96)";
|
|
201
|
-
renderButtonIcon();
|
|
202
|
-
}
|
|
203
|
-
|
|
204
216
|
function anchorContainerToButton() {
|
|
205
217
|
var rect = button.getBoundingClientRect();
|
|
206
218
|
var useLeft = rect.left + rect.width / 2 < window.innerWidth / 2;
|
|
@@ -249,6 +261,52 @@
|
|
|
249
261
|
anchorContainerToButton();
|
|
250
262
|
};
|
|
251
263
|
|
|
264
|
+
var frameDrag = null;
|
|
265
|
+
handleFrameDrag = function (data) {
|
|
266
|
+
if (data.phase === "start") {
|
|
267
|
+
var buttonRect = button.getBoundingClientRect();
|
|
268
|
+
var containerRect = container.getBoundingClientRect();
|
|
269
|
+
frameDrag = {
|
|
270
|
+
buttonLeft: buttonRect.left,
|
|
271
|
+
buttonTop: buttonRect.top,
|
|
272
|
+
containerLeft: containerRect.left,
|
|
273
|
+
containerTop: containerRect.top,
|
|
274
|
+
minX: 8 - Math.min(buttonRect.left, containerRect.left),
|
|
275
|
+
maxX:
|
|
276
|
+
window.innerWidth -
|
|
277
|
+
8 -
|
|
278
|
+
Math.max(buttonRect.right, containerRect.right),
|
|
279
|
+
minY: 8 - Math.min(buttonRect.top, containerRect.top),
|
|
280
|
+
maxY:
|
|
281
|
+
window.innerHeight -
|
|
282
|
+
8 -
|
|
283
|
+
Math.max(buttonRect.bottom, containerRect.bottom),
|
|
284
|
+
};
|
|
285
|
+
container.style.height = containerRect.height + "px";
|
|
286
|
+
container.style.minHeight = containerRect.height + "px";
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
if (!frameDrag) return;
|
|
290
|
+
if (data.phase === "move") {
|
|
291
|
+
var offsetX = Math.max(
|
|
292
|
+
frameDrag.minX,
|
|
293
|
+
Math.min(frameDrag.maxX, data.dx),
|
|
294
|
+
);
|
|
295
|
+
var offsetY = Math.max(
|
|
296
|
+
frameDrag.minY,
|
|
297
|
+
Math.min(frameDrag.maxY, data.dy),
|
|
298
|
+
);
|
|
299
|
+
button.style.left = frameDrag.buttonLeft + offsetX + "px";
|
|
300
|
+
button.style.top = frameDrag.buttonTop + offsetY + "px";
|
|
301
|
+
container.style.left = frameDrag.containerLeft + offsetX + "px";
|
|
302
|
+
container.style.top = frameDrag.containerTop + offsetY + "px";
|
|
303
|
+
container.style.bottom = "auto";
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
frameDrag = null;
|
|
307
|
+
anchorContainerToButton();
|
|
308
|
+
};
|
|
309
|
+
|
|
252
310
|
var dragState = null;
|
|
253
311
|
var suppressClickUntil = 0;
|
|
254
312
|
button.addEventListener("pointerdown", function (event) {
|
|
@@ -299,9 +357,10 @@
|
|
|
299
357
|
button.addEventListener("click", function () {
|
|
300
358
|
if (Date.now() < suppressClickUntil) return;
|
|
301
359
|
opened = !opened;
|
|
302
|
-
|
|
360
|
+
renderFloatingState();
|
|
303
361
|
});
|
|
304
362
|
|
|
363
|
+
renderFloatingState();
|
|
305
364
|
document.body.appendChild(container);
|
|
306
365
|
document.body.appendChild(button);
|
|
307
366
|
window.addEventListener("resize", updateViewportPosition);
|
|
@@ -313,7 +372,6 @@
|
|
|
313
372
|
);
|
|
314
373
|
}
|
|
315
374
|
updateViewportPosition();
|
|
316
|
-
renderOpenState();
|
|
317
375
|
}
|
|
318
376
|
|
|
319
377
|
async function authenticate() {
|
|
@@ -352,6 +410,15 @@
|
|
|
352
410
|
event.data.type === MESSAGE_REQUEST_AUTH
|
|
353
411
|
) {
|
|
354
412
|
authenticate();
|
|
413
|
+
} else if (
|
|
414
|
+
event.data.type === MESSAGE_DRAG &&
|
|
415
|
+
handleFrameDrag &&
|
|
416
|
+
options.draggable !== false &&
|
|
417
|
+
["start", "move", "end"].includes(event.data.phase) &&
|
|
418
|
+
Number.isFinite(event.data.dx) &&
|
|
419
|
+
Number.isFinite(event.data.dy)
|
|
420
|
+
) {
|
|
421
|
+
handleFrameDrag(event.data);
|
|
355
422
|
} else if (
|
|
356
423
|
event.data.type === MESSAGE_ERROR &&
|
|
357
424
|
typeof options.onError === "function"
|
|
@@ -367,14 +434,7 @@
|
|
|
367
434
|
function setOpened(next) {
|
|
368
435
|
if (destroyed || target) return;
|
|
369
436
|
opened = next;
|
|
370
|
-
|
|
371
|
-
container.style.visibility = opened ? "visible" : "hidden";
|
|
372
|
-
container.style.pointerEvents = opened ? "auto" : "none";
|
|
373
|
-
container.style.transform = opened ? "scale(1)" : "scale(.96)";
|
|
374
|
-
if (button) {
|
|
375
|
-
button.replaceChildren(opened ? closeIcon : openIcon);
|
|
376
|
-
button.setAttribute("aria-expanded", opened ? "true" : "false");
|
|
377
|
-
}
|
|
437
|
+
renderFloatingState();
|
|
378
438
|
}
|
|
379
439
|
|
|
380
440
|
return {
|