feat: Add torch system for multi-browser MCP control
- Add TorchButton component to header (replaces dropdowns) - Add torch store for managing torch state - Add torch service for requesting/releasing torch - Add torch event handlers in WebMCP service - Remove ComponentsDropdown and ToolsDropdown from header The torch system allows controlling which browser receives MCP tool calls when multiple browsers are connected. Requires WebMCP library update to fully function.
This commit is contained in:
117
frontend/src/components/TorchButton.vue
Normal file
117
frontend/src/components/TorchButton.vue
Normal file
@@ -0,0 +1,117 @@
|
||||
<script setup lang="ts">
|
||||
import { useTorchStore } from '../stores/torch'
|
||||
import { requestTorch, releaseTorch } from '../services/torch'
|
||||
|
||||
const torchStore = useTorchStore()
|
||||
|
||||
async function handleClick() {
|
||||
if (torchStore.hasTorch) {
|
||||
await releaseTorch()
|
||||
} else {
|
||||
await requestTorch()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<button
|
||||
class="torch-btn"
|
||||
:class="{
|
||||
'has-torch': torchStore.hasTorch,
|
||||
'torch-held': torchStore.torchHolderId && !torchStore.hasTorch,
|
||||
'requesting': torchStore.isRequesting
|
||||
}"
|
||||
@click="handleClick"
|
||||
:title="torchStore.hasTorch ? 'You have the torch - click to release' : torchStore.torchHolderId ? 'Torch held by another client - click to request' : 'Click to request the torch'"
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<!-- Torch/flame icon -->
|
||||
<path d="M12 2c1 3 2.5 3.5 3.5 4.5A5 5 0 0 1 17 10a5 5 0 0 1-5 5 5 5 0 0 1-5-5 5 5 0 0 1 1.5-3.5C9.5 5.5 11 5 12 2z"/>
|
||||
<path d="M12 15v7"/>
|
||||
<path d="M10 22h4"/>
|
||||
</svg>
|
||||
<span v-if="torchStore.isRequesting" class="requesting-indicator"></span>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.torch-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 6px 10px;
|
||||
background: var(--bg-secondary);
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 6px;
|
||||
color: var(--text-secondary);
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.torch-btn:hover {
|
||||
background: var(--bg-tertiary);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
/* Has the torch - golden glow */
|
||||
.torch-btn.has-torch {
|
||||
background: linear-gradient(135deg, #ff9500 0%, #ff6b00 100%);
|
||||
border-color: #ff9500;
|
||||
color: white;
|
||||
box-shadow: 0 0 12px rgba(255, 149, 0, 0.5);
|
||||
animation: torch-glow 2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.torch-btn.has-torch:hover {
|
||||
background: linear-gradient(135deg, #ffaa33 0%, #ff8533 100%);
|
||||
}
|
||||
|
||||
/* Torch held by another */
|
||||
.torch-btn.torch-held {
|
||||
background: var(--bg-secondary);
|
||||
border-color: #ff9500;
|
||||
color: #ff9500;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.torch-btn.torch-held:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* Requesting state */
|
||||
.torch-btn.requesting {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.requesting-indicator {
|
||||
position: absolute;
|
||||
top: -2px;
|
||||
right: -2px;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
background: var(--accent-color);
|
||||
border-radius: 50%;
|
||||
animation: pulse 1s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes torch-glow {
|
||||
0%, 100% {
|
||||
box-shadow: 0 0 12px rgba(255, 149, 0, 0.5);
|
||||
}
|
||||
50% {
|
||||
box-shadow: 0 0 20px rgba(255, 149, 0, 0.8);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0%, 100% {
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
50% {
|
||||
transform: scale(1.2);
|
||||
opacity: 0.7;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user