|
@@ -46,6 +46,9 @@ class ChatUI {
|
|
|
this.isTyping = false; // 添加打字状态标记
|
|
|
this.loadingDiv = null; // 添加加载动画的引用
|
|
|
this.inputWrapper = document.querySelector(".input-wrapper");
|
|
|
+
|
|
|
+ // 初始化页面信息卡片
|
|
|
+ this.initPageInfoCard();
|
|
|
}
|
|
|
|
|
|
async init() {
|
|
@@ -146,7 +149,7 @@ class ChatUI {
|
|
|
await this.addMessage(response, "assistant", true);
|
|
|
|
|
|
this.stopButton.classList.remove("show");
|
|
|
- this.setInputState(false); // 恢复输入框
|
|
|
+ this.setInputState(false); // 这里会自动聚焦输入框
|
|
|
|
|
|
this.aiService.updateContext(response, "assistant");
|
|
|
} catch (error) {
|
|
@@ -156,7 +159,7 @@ class ChatUI {
|
|
|
}
|
|
|
|
|
|
this.stopButton.classList.remove("show");
|
|
|
- this.setInputState(false); // 恢复输入框
|
|
|
+ this.setInputState(false); // 这里也会自动聚焦输入框
|
|
|
this.isTyping = false;
|
|
|
|
|
|
if (error.message === "REQUEST_ABORTED") {
|
|
@@ -481,7 +484,7 @@ class ChatUI {
|
|
|
}
|
|
|
|
|
|
this.stopButton.classList.remove("show");
|
|
|
- this.setInputState(false); // 恢复输入框状态
|
|
|
+ this.setInputState(false); // 中断后也自动聚焦输入框
|
|
|
|
|
|
this.addMessage("用户手动停止生成", "assistant", false, true);
|
|
|
} catch (error) {
|
|
@@ -497,6 +500,88 @@ class ChatUI {
|
|
|
this.inputWrapper.classList.add("generating");
|
|
|
} else {
|
|
|
this.inputWrapper.classList.remove("generating");
|
|
|
+ // AI回复完成后,自动聚焦到输入框
|
|
|
+ this.input.focus();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 初始化页面信息卡片
|
|
|
+ */
|
|
|
+ initPageInfoCard() {
|
|
|
+ // 从父窗口获取页面信息
|
|
|
+ window.addEventListener("message", (event) => {
|
|
|
+ if (event.data.type === "PAGE_INFO") {
|
|
|
+ const pageInfo = event.data.pageInfo;
|
|
|
+
|
|
|
+ // 更新卡片内容
|
|
|
+ const favicon = document.querySelector(".page-favicon");
|
|
|
+ const title = document.querySelector(".page-title");
|
|
|
+
|
|
|
+ // 设置网站图标
|
|
|
+ favicon.src = pageInfo.favicon;
|
|
|
+ favicon.onerror = () => {
|
|
|
+ // 如果图标加载失败,使用默认图标
|
|
|
+ favicon.src = chrome.runtime.getURL("images/icon16.png");
|
|
|
+ };
|
|
|
+
|
|
|
+ // 设置页面标题
|
|
|
+ title.textContent = pageInfo.title;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取页面favicon
|
|
|
+ * @returns {string} favicon URL
|
|
|
+ */
|
|
|
+ getPageFavicon() {
|
|
|
+ // 尝试获取页面favicon
|
|
|
+ const iconLink = document.querySelector('link[rel*="icon"]');
|
|
|
+ if (iconLink) return iconLink.href;
|
|
|
+
|
|
|
+ // 如果没有找到,返回网站根目录的favicon.ico
|
|
|
+ const url = new URL(window.location.href);
|
|
|
+ return `${url.protocol}//${url.hostname}/favicon.ico`;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 处理总结请求
|
|
|
+ */
|
|
|
+ async handleSummarize() {
|
|
|
+ try {
|
|
|
+ // 显示加载状态
|
|
|
+ this.setInputState(true);
|
|
|
+ this.loadingDiv = this.createLoadingMessage();
|
|
|
+
|
|
|
+ // 获取页面分析结果
|
|
|
+ const pageContext = window.pageAnalyzer.analyzePage();
|
|
|
+
|
|
|
+ // 构建提示词
|
|
|
+ const prompt = `请总结当前页面的主要内容:
|
|
|
+标题:${pageContext.title}
|
|
|
+URL:${pageContext.url}
|
|
|
+主要内容:${pageContext.mainContent}`;
|
|
|
+
|
|
|
+ // 发送分析请求
|
|
|
+ const response = await this.aiService.sendMessage(prompt);
|
|
|
+
|
|
|
+ // 显示分析结果
|
|
|
+ if (this.loadingDiv) {
|
|
|
+ this.loadingDiv.remove();
|
|
|
+ this.loadingDiv = null;
|
|
|
+ }
|
|
|
+
|
|
|
+ await this.addMessage(response, "assistant", true);
|
|
|
+ this.setInputState(false); // 总结完成后自动聚焦输入框
|
|
|
+ } catch (error) {
|
|
|
+ console.error("Failed to summarize page:", error);
|
|
|
+ this.addMessage(
|
|
|
+ "抱歉,页面总结过程中出现错误,请稍后重试。",
|
|
|
+ "assistant",
|
|
|
+ false
|
|
|
+ );
|
|
|
+ this.setInputState(false); // 错误后也自动聚焦输入框
|
|
|
}
|
|
|
}
|
|
|
}
|