修复关闭标签页 key 重排序错误的问题
This commit is contained in:
parent
4f9900a64c
commit
a535690bc6
24
renderer/package-lock.json
generated
24
renderer/package-lock.json
generated
@ -14,6 +14,7 @@
|
||||
"markdown-it": "^14.1.0",
|
||||
"markdown-it-katex": "^2.0.3",
|
||||
"openai": "^4.93.0",
|
||||
"uuid": "^11.1.0",
|
||||
"vue": "^3.2.13",
|
||||
"vue-i18n": "^11.1.0",
|
||||
"vue-router": "^4.0.3"
|
||||
@ -11820,6 +11821,16 @@
|
||||
"websocket-driver": "^0.7.4"
|
||||
}
|
||||
},
|
||||
"node_modules/sockjs/node_modules/uuid": {
|
||||
"version": "8.3.2",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
|
||||
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"uuid": "dist/bin/uuid"
|
||||
}
|
||||
},
|
||||
"node_modules/source-map": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz",
|
||||
@ -12970,13 +12981,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/uuid": {
|
||||
"version": "8.3.2",
|
||||
"resolved": "https://registry.npmmirror.com/uuid/-/uuid-8.3.2.tgz",
|
||||
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
|
||||
"dev": true,
|
||||
"version": "11.1.0",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz",
|
||||
"integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==",
|
||||
"funding": [
|
||||
"https://github.com/sponsors/broofa",
|
||||
"https://github.com/sponsors/ctavan"
|
||||
],
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"uuid": "dist/bin/uuid"
|
||||
"uuid": "dist/esm/bin/uuid"
|
||||
}
|
||||
},
|
||||
"node_modules/v8-compile-cache": {
|
||||
|
@ -14,6 +14,7 @@
|
||||
"markdown-it": "^14.1.0",
|
||||
"markdown-it-katex": "^2.0.3",
|
||||
"openai": "^4.93.0",
|
||||
"uuid": "^11.1.0",
|
||||
"vue": "^3.2.13",
|
||||
"vue-i18n": "^11.1.0",
|
||||
"vue-router": "^4.0.3"
|
||||
|
@ -22,7 +22,7 @@
|
||||
--vscode-scrollbarSlider-activeBackground: rgba(0, 0, 0, 0.6);
|
||||
--vscode-progressBar-background: #0e70c0;
|
||||
--vscode-editor-background: #ffffff;
|
||||
--vscode-editor-foreground: #000000;
|
||||
--vscode-editor-foreground: #3d3d3d;
|
||||
--vscode-editorStickyScroll-background: #ffffff;
|
||||
--vscode-editorStickyScrollHover-background: #f0f0f0;
|
||||
--vscode-editorStickyScroll-shadow: #dddddd;
|
||||
|
@ -7,7 +7,7 @@
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<meta name="referrer" content="no-referrer">
|
||||
<link rel="icon" href="<%= BASE_URL %>favicon.svg">
|
||||
<link rel="stylesheet" href="default-dark.css">
|
||||
<link rel="stylesheet" href="default-light.css">
|
||||
<link rel="stylesheet" href="vscode.css">
|
||||
<link rel="stylesheet" href="mcp.css">
|
||||
<link rel="stylesheet" href="iconfont.css">
|
||||
|
@ -29,8 +29,8 @@ bridge.addCommandListener('hello', data => {
|
||||
|
||||
|
||||
function initDebug() {
|
||||
// connectionArgs.commandString = 'node /Users/bytedance/projects/mcp/servers/src/puppeteer/dist/index.js';
|
||||
connectionArgs.commandString = 'node C:/Users/K/code/servers/src/puppeteer/dist/index.js';
|
||||
connectionArgs.commandString = 'node /Users/bytedance/projects/mcp/servers/src/puppeteer/dist/index.js';
|
||||
// connectionArgs.commandString = 'node C:/Users/K/code/servers/src/puppeteer/dist/index.js';
|
||||
// connectionArgs.commandString = 'uv run mcp run bing-picture.py';
|
||||
connectionArgs.cwd = '../servers';
|
||||
connectionMethods.current = 'STDIO';
|
||||
@ -107,4 +107,8 @@ onMounted(() => {
|
||||
max-width: 300px;
|
||||
}
|
||||
|
||||
|
||||
.icon-chat:before {
|
||||
font-weight: 1000;
|
||||
}
|
||||
</style>
|
||||
|
@ -5,25 +5,32 @@
|
||||
</div>
|
||||
|
||||
<div v-else-if="props.item.type === 'image'" class="tool-image">
|
||||
<div class="media-item">
|
||||
<img :src="thumbnail" alt="screenshot"/>
|
||||
<div class="media-item" @click="showFullImage">
|
||||
<img :src="thumbnail" alt="screenshot" />
|
||||
<span class="float-container">
|
||||
<span class="iconfont icon-image"></span>
|
||||
|
||||
<!-- 后处理结束后显示的部分 -->
|
||||
<span class="iconfont icon-image" v-if="finishProcess"></span>
|
||||
|
||||
<!-- 后处理时显示的部分 -->
|
||||
<el-progress v-else
|
||||
class="progress"
|
||||
:percentage="progress"
|
||||
:stroke-width="5"
|
||||
type="circle"
|
||||
:width="80"
|
||||
color="var(--main-color)"
|
||||
>
|
||||
<template #default="{ percentage }">
|
||||
<div class="progress-label">
|
||||
<span class="percentage-value">{{ percentage }}%</span>
|
||||
<span class="percentage-label">{{ progressText }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</el-progress>
|
||||
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<span v-if="!finishProcess">
|
||||
<el-progress
|
||||
class="progress"
|
||||
:percentage="progress"
|
||||
:stroke-width="3"
|
||||
>
|
||||
<template #default="{ percentage }">
|
||||
<span class="percentage-label">{{ progressText }}</span>
|
||||
<span class="percentage-value">{{ percentage }}%</span>
|
||||
</template>
|
||||
</el-progress>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div v-else class="tool-other">{{ JSON.stringify(props.item) }}</div>
|
||||
@ -62,7 +69,7 @@ if (ocr) {
|
||||
const { id, progress: p = 1.0, status = 'finish' } = data;
|
||||
if (id === workerId) {
|
||||
progressText.value = status;
|
||||
progress.value = Math.min(Math.ceil(Math.max(p * 100 ,0)), 100);
|
||||
progress.value = Math.min(Math.ceil(Math.max(p * 100, 0)), 100);
|
||||
}
|
||||
}, { once: false });
|
||||
|
||||
@ -95,6 +102,41 @@ if (props.item.data) {
|
||||
});
|
||||
}
|
||||
|
||||
const showFullImage = () => {
|
||||
const img = new Image();
|
||||
img.src = thumbnail.value;
|
||||
img.onload = () => {
|
||||
const overlay = document.createElement('div');
|
||||
overlay.style.position = 'fixed';
|
||||
overlay.style.top = '0';
|
||||
overlay.style.left = '0';
|
||||
overlay.style.width = '100%';
|
||||
overlay.style.height = '100%';
|
||||
overlay.style.backgroundColor = 'rgba(0, 0, 0, 0.8)';
|
||||
overlay.style.zIndex = '9999';
|
||||
overlay.style.display = 'flex';
|
||||
overlay.style.justifyContent = 'center';
|
||||
overlay.style.alignItems = 'center';
|
||||
overlay.onclick = () => document.body.removeChild(overlay);
|
||||
|
||||
const imgContainer = document.createElement('div');
|
||||
imgContainer.style.maxWidth = '90vw';
|
||||
imgContainer.style.maxHeight = '90vh';
|
||||
imgContainer.style.overflow = 'auto';
|
||||
|
||||
const fullImg = new Image();
|
||||
fullImg.src = thumbnail.value;
|
||||
fullImg.style.width = 'auto';
|
||||
fullImg.style.height = 'auto';
|
||||
fullImg.style.maxWidth = '100%';
|
||||
fullImg.style.maxHeight = '100%';
|
||||
|
||||
imgContainer.appendChild(fullImg);
|
||||
overlay.appendChild(imgContainer);
|
||||
document.body.appendChild(overlay);
|
||||
};
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
@ -106,10 +148,6 @@ if (props.item.data) {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.percentage-label {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.tool-image .media-item {
|
||||
position: relative;
|
||||
width: 100px;
|
||||
@ -130,7 +168,7 @@ if (props.item.data) {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.tool-image .media-item > img {
|
||||
.tool-image .media-item>img {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
height: 100%;
|
||||
@ -145,7 +183,7 @@ if (props.item.data) {
|
||||
top: 0;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
opacity: 1;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
@ -153,6 +191,25 @@ if (props.item.data) {
|
||||
transition: var(--animation-3s);
|
||||
}
|
||||
|
||||
.progress-label {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.percentage-label {
|
||||
max-width: 50px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.percentage-value {
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.tool-image .media-item .float-container .iconfont {
|
||||
color: var(--background);
|
||||
}
|
||||
@ -161,4 +218,11 @@ if (props.item.data) {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.media-item {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.media-item:hover {
|
||||
opacity: 0.9;
|
||||
}
|
||||
</style>
|
@ -45,7 +45,7 @@
|
||||
反馈
|
||||
</el-button>
|
||||
</span>
|
||||
<span style="width: 200px;" class="tools-dialog-container" v-if="isValid">
|
||||
<span style="width: 200px;" class="tools-dialog-container" v-if="currentMessageLevel === 'info'">
|
||||
<el-switch v-model="props.message.showJson!.value" inline-prompt active-text="JSON"
|
||||
inactive-text="Text" style="margin-left: 10px; width: 200px;"
|
||||
:inactive-action-style="'backgroundColor: var(--sidebar)'" />
|
||||
|
@ -312,7 +312,7 @@ export class TaskLoop {
|
||||
|
||||
const toolCallResult = await this.handleToolCalls(this.streamingToolCalls.value);
|
||||
|
||||
console.log(toolCallResult);
|
||||
console.log('toolCallResult', toolCallResult);
|
||||
|
||||
if (toolCallResult.state === MessageState.ParseJsonError) {
|
||||
// 如果是因为解析 JSON 错误,则重新开始
|
||||
|
@ -6,7 +6,7 @@
|
||||
<span
|
||||
class="tab"
|
||||
v-for="(tab, index) of tabs.content"
|
||||
:key="index"
|
||||
:key="tab.id"
|
||||
:class="{ 'active-tab': tabs.activeIndex === index }"
|
||||
@click="setActiveTab(index)"
|
||||
>
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { watch, reactive } from 'vue';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
import Resource from './resource/index.vue';
|
||||
import Chat from './chat/index.vue';
|
||||
@ -11,6 +11,7 @@ import { safeSavePanels, savePanels } from '@/hook/panel';
|
||||
const { t } = I18n.global;
|
||||
|
||||
interface Tab {
|
||||
id: string;
|
||||
name: string;
|
||||
icon: string;
|
||||
type: string;
|
||||
@ -52,6 +53,7 @@ watch(
|
||||
|
||||
export function createTab(type: string, index: number): Tab {
|
||||
let customName: string | null = null;
|
||||
const id = uuidv4();
|
||||
|
||||
return {
|
||||
get name() {
|
||||
@ -65,6 +67,7 @@ export function createTab(type: string, index: number): Tab {
|
||||
},
|
||||
icon: 'icon-blank',
|
||||
type,
|
||||
id,
|
||||
componentIndex: -1,
|
||||
component: undefined,
|
||||
storage: {},
|
||||
@ -83,6 +86,8 @@ export function closeTab(index: number) {
|
||||
|
||||
tabs.content.splice(index, 1);
|
||||
|
||||
console.log(tabs.content);
|
||||
|
||||
// 调整活动标签索引
|
||||
if (tabs.activeIndex >= index) {
|
||||
tabs.activeIndex = Math.max(0, tabs.activeIndex - 1);
|
||||
|
@ -2,6 +2,7 @@ import { useMessageBridge } from "@/api/message-bridge";
|
||||
import { pinkLog } from "@/views/setting/util";
|
||||
import { debugModes, tabs } from "@/components/main-panel/panel";
|
||||
import { markRaw, ref, nextTick } from "vue";
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
interface SaveTabItem {
|
||||
name: string;
|
||||
@ -48,6 +49,7 @@ export function loadPanels() {
|
||||
const component = tab.componentIndex >= 0? markRaw(debugModes[tab.componentIndex]) : undefined;
|
||||
|
||||
tabs.content.push({
|
||||
id: uuidv4(),
|
||||
name: tab.name,
|
||||
icon: tab.icon,
|
||||
type: tab.type,
|
||||
@ -76,7 +78,7 @@ export function safeSavePanels() {
|
||||
clearTimeout(debounceHandler);
|
||||
debounceHandler = setTimeout(() => {
|
||||
savePanels();
|
||||
}, 1000);
|
||||
}, 100);
|
||||
}
|
||||
|
||||
export function savePanels(saveHandler?: () => void) {
|
||||
|
@ -8,7 +8,7 @@
|
||||
<component
|
||||
v-show="tab === tabs.content[tabs.activeIndex]"
|
||||
v-for="(tab, index) of tabs.content"
|
||||
:key="index"
|
||||
:key="tab.id"
|
||||
:is="tab.component"
|
||||
:tab-id="index"
|
||||
/>
|
||||
|
Loading…
x
Reference in New Issue
Block a user