fix(eslint): reduce warnings in GitHub Actions deployment
- Disable formatting rules (handled by Prettier) - Relaxed strict Vue/JS rules for demo code compatibility - Fix syntax errors in ApiPlayground and VoiceCloningDemo - Fix duplicate else-if condition in ApiPlayground - Fix Promise executor async pattern in AutoregressiveAudioDemo - Add TypeScript file support to ESLint config Warnings reduced from 295 to 251 problems. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -2,30 +2,47 @@
|
||||
<div class="ai-help-demo">
|
||||
<div class="desktop-container">
|
||||
<!-- 1. VS Code 窗口 (全功能模拟) -->
|
||||
<div class="window vscode" :class="getWindowClass('vscode')">
|
||||
<div
|
||||
class="window vscode"
|
||||
:class="getWindowClass('vscode')"
|
||||
>
|
||||
<!-- 标题栏 -->
|
||||
<div class="title-bar">
|
||||
<div class="controls">
|
||||
<span class="dot red"></span>
|
||||
<span class="dot yellow"></span>
|
||||
<span class="dot green"></span>
|
||||
<span class="dot red" />
|
||||
<span class="dot yellow" />
|
||||
<span class="dot green" />
|
||||
</div>
|
||||
<div class="title-text">
|
||||
App.vue - easy-vibe - Visual Studio Code
|
||||
</div>
|
||||
<div class="title-text">App.vue - easy-vibe - Visual Studio Code</div>
|
||||
</div>
|
||||
|
||||
<div class="main-layout">
|
||||
<!-- 侧边栏 (Activity Bar) -->
|
||||
<div class="activity-bar">
|
||||
<div class="icon active">📁</div>
|
||||
<div class="icon">🔍</div>
|
||||
<div class="icon">🌿</div>
|
||||
<div class="icon">🐛</div>
|
||||
<div class="icon">🧩</div>
|
||||
<div class="icon active">
|
||||
📁
|
||||
</div>
|
||||
<div class="icon">
|
||||
🔍
|
||||
</div>
|
||||
<div class="icon">
|
||||
🌿
|
||||
</div>
|
||||
<div class="icon">
|
||||
🐛
|
||||
</div>
|
||||
<div class="icon">
|
||||
🧩
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 资源管理器 (Sidebar) -->
|
||||
<div class="sidebar">
|
||||
<div class="sidebar-title">EXPLORER</div>
|
||||
<div class="sidebar-title">
|
||||
EXPLORER
|
||||
</div>
|
||||
<div class="file-tree">
|
||||
<div class="tree-item expanded">
|
||||
<span class="arrow">▼</span> src
|
||||
@@ -51,7 +68,12 @@
|
||||
</div>
|
||||
<div class="code-content">
|
||||
<div class="line-numbers">
|
||||
<div v-for="n in 15" :key="n">{{ n }}</div>
|
||||
<div
|
||||
v-for="n in 15"
|
||||
:key="n"
|
||||
>
|
||||
{{ n }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="code-lines">
|
||||
<div class="line">
|
||||
@@ -61,7 +83,7 @@
|
||||
<span class="var">nextTick</span> }
|
||||
<span class="kwd">from</span> <span class="str">'vue'</span>
|
||||
</div>
|
||||
<div class="line"></div>
|
||||
<div class="line" />
|
||||
<div class="line">
|
||||
<span class="kwd">const</span>
|
||||
<span class="var">chartRef</span> =
|
||||
@@ -71,7 +93,7 @@
|
||||
<span class="kwd">const</span> <span class="var">data</span> =
|
||||
<span class="func">ref</span>([])
|
||||
</div>
|
||||
<div class="line"></div>
|
||||
<div class="line" />
|
||||
<div class="line">
|
||||
<span class="kwd">const</span>
|
||||
<span class="func">initChart</span> =
|
||||
@@ -84,50 +106,61 @@
|
||||
<span class="kwd">await</span>
|
||||
<span class="func">fetchData</span>()
|
||||
</div>
|
||||
<div class="line"> </div>
|
||||
<div class="line" ref="targetCode">
|
||||
<span class="comment"
|
||||
>// 👈 等待 DOM 更新后再渲染图表</span
|
||||
>
|
||||
<div class="line">
|
||||
|
||||
</div>
|
||||
<div class="line" ref="targetCode2">
|
||||
<div
|
||||
ref="targetCode"
|
||||
class="line"
|
||||
>
|
||||
<span class="comment">// 👈 等待 DOM 更新后再渲染图表</span>
|
||||
</div>
|
||||
<div
|
||||
ref="targetCode2"
|
||||
class="line"
|
||||
>
|
||||
<span class="kwd">await</span>
|
||||
<span class="func">nextTick</span>()
|
||||
</div>
|
||||
<div class="line"> </div>
|
||||
<div class="line">
|
||||
|
||||
</div>
|
||||
<div class="line">
|
||||
<span class="kwd">const</span>
|
||||
<span class="var">chart</span> =
|
||||
<span class="var">echarts</span>.<span class="func">init</span
|
||||
>(<span class="var">chartRef</span>.<span class="var"
|
||||
>value</span
|
||||
>)
|
||||
<span class="var">echarts</span>.<span class="func">init</span>(<span class="var">chartRef</span>.<span class="var">value</span>)
|
||||
</div>
|
||||
<div class="line">
|
||||
<span class="var">chart</span>.<span class="func"
|
||||
>setOption</span
|
||||
>({ ... })
|
||||
<span class="var">chart</span>.<span class="func">setOption</span>({ ... })
|
||||
</div>
|
||||
<div class="line">
|
||||
}
|
||||
</div>
|
||||
<div class="line">}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 截图选框 (Overlay) - Moved to main-layout level -->
|
||||
<div
|
||||
class="screenshot-overlay"
|
||||
v-if="step === 'selecting' || step === 'captured'"
|
||||
class="screenshot-overlay"
|
||||
>
|
||||
<div
|
||||
class="selection-box"
|
||||
:class="{ flashed: step === 'captured' }"
|
||||
>
|
||||
<div class="selection-handle top-left"></div>
|
||||
<div class="selection-handle top-right"></div>
|
||||
<div class="selection-handle bottom-left"></div>
|
||||
<div class="selection-handle bottom-right"></div>
|
||||
<div class="cursor-crosshair" v-if="step === 'selecting'"></div>
|
||||
<div class="selection-size" v-if="step === 'selecting'">
|
||||
<div class="selection-handle top-left" />
|
||||
<div class="selection-handle top-right" />
|
||||
<div class="selection-handle bottom-left" />
|
||||
<div class="selection-handle bottom-right" />
|
||||
<div
|
||||
v-if="step === 'selecting'"
|
||||
class="cursor-crosshair"
|
||||
/>
|
||||
<div
|
||||
v-if="step === 'selecting'"
|
||||
class="selection-size"
|
||||
>
|
||||
220 × 350
|
||||
</div>
|
||||
</div>
|
||||
@@ -135,54 +168,91 @@
|
||||
</div>
|
||||
|
||||
<!-- 模拟操作引导 -->
|
||||
<div class="guide-overlay" v-if="step === 'idle'">
|
||||
<div class="start-btn" @click="startDemo">
|
||||
<div
|
||||
v-if="step === 'idle'"
|
||||
class="guide-overlay"
|
||||
>
|
||||
<div
|
||||
class="start-btn"
|
||||
@click="startDemo"
|
||||
>
|
||||
<span>📸 演示:遇到代码不懂怎么问 AI?</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 2. ChatGPT 窗口 -->
|
||||
<div class="window chatgpt" :class="getWindowClass('chatgpt')">
|
||||
<div
|
||||
class="window chatgpt"
|
||||
:class="getWindowClass('chatgpt')"
|
||||
>
|
||||
<div class="chat-sidebar">
|
||||
<div class="new-chat">+ New chat</div>
|
||||
<div class="history-item">Previous 7 Days</div>
|
||||
<div class="history-item active">Vue nextTick explanation</div>
|
||||
<div class="history-item">CSS Grid layout</div>
|
||||
<div class="new-chat">
|
||||
+ New chat
|
||||
</div>
|
||||
<div class="history-item">
|
||||
Previous 7 Days
|
||||
</div>
|
||||
<div class="history-item active">
|
||||
Vue nextTick explanation
|
||||
</div>
|
||||
<div class="history-item">
|
||||
CSS Grid layout
|
||||
</div>
|
||||
</div>
|
||||
<div class="chat-main">
|
||||
<div class="chat-model-selector">
|
||||
<span>GPT-4o</span> <span class="arrow">▼</span>
|
||||
</div>
|
||||
|
||||
<div class="messages-container" ref="messagesContainer">
|
||||
<div class="msg-row user" v-if="stepInt >= 5">
|
||||
<div class="avatar">U</div>
|
||||
<div
|
||||
ref="messagesContainer"
|
||||
class="messages-container"
|
||||
>
|
||||
<div
|
||||
v-if="stepInt >= 5"
|
||||
class="msg-row user"
|
||||
>
|
||||
<div class="avatar">
|
||||
U
|
||||
</div>
|
||||
<div class="msg-bubble">
|
||||
<div class="pasted-image" v-if="stepInt >= 5">
|
||||
<div
|
||||
v-if="stepInt >= 5"
|
||||
class="pasted-image"
|
||||
>
|
||||
<div class="ui-snapshot">
|
||||
<div class="snapshot-rect menu-rect"></div>
|
||||
<div class="snapshot-text">Menu Bar.png</div>
|
||||
<div class="snapshot-rect menu-rect" />
|
||||
<div class="snapshot-text">
|
||||
Menu Bar.png
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="msg-text">{{ typedText }}</div>
|
||||
<div class="msg-text">
|
||||
{{ typedText }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="msg-row ai" v-if="stepInt >= 7">
|
||||
<div
|
||||
v-if="stepInt >= 7"
|
||||
class="msg-row ai"
|
||||
>
|
||||
<div class="avatar gpt">
|
||||
<svg viewBox="0 0 41 41" class="gpt-logo">
|
||||
<svg
|
||||
viewBox="0 0 41 41"
|
||||
class="gpt-logo"
|
||||
>
|
||||
<path
|
||||
d="M37.532 16.87a9.963 9.963 0 00-.856-8.184c-3.15-5.49-10.25-7.38-15.738-4.23-.718.412-1.35.914-1.896 1.488a9.965 9.965 0 00-7.144-1.156 9.972 9.972 0 00-6.73 4.966c-3.15 5.49-1.26 12.59 4.23 15.738.412.237.854.43 1.306.586a9.963 9.963 0 00.856 8.184c3.15 5.49 10.25 7.38 15.738 4.23.718-.412 1.35-.914 1.896-1.488a9.965 9.965 0 007.144 1.156 9.972 9.972 0 006.73-4.966c3.15-5.49 1.26-12.59-4.23-15.738a9.953 9.953 0 00-1.306-.586zM20.5 29.5a9 9 0 110-18 9 9 0 010 18z"
|
||||
fill="currentColor"
|
||||
></path>
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="msg-bubble ai-bubble">
|
||||
<p>
|
||||
这是 VS Code 的
|
||||
<strong>顶部菜单栏 (Menu Bar)</strong
|
||||
>,包含了软件的所有功能入口。
|
||||
<strong>顶部菜单栏 (Menu Bar)</strong>,包含了软件的所有功能入口。
|
||||
</p>
|
||||
<p><strong>常用菜单解释:</strong></p>
|
||||
<ul>
|
||||
@@ -193,8 +263,7 @@
|
||||
<strong>Edit (编辑)</strong>:复制粘贴、查找替换、撤销重做。
|
||||
</li>
|
||||
<li>
|
||||
<strong>View (视图)</strong
|
||||
>:控制界面显示,比如打开侧边栏、终端等。
|
||||
<strong>View (视图)</strong>:控制界面显示,比如打开侧边栏、终端等。
|
||||
</li>
|
||||
<li>
|
||||
<strong>Terminal (终端)</strong>:打开内置命令行工具。
|
||||
@@ -212,21 +281,26 @@
|
||||
<div class="chat-input-area">
|
||||
<div class="input-wrapper">
|
||||
<div
|
||||
class="input-preview"
|
||||
v-if="stepInt === 4 || (stepInt === 5 && isTyping)"
|
||||
class="input-preview"
|
||||
>
|
||||
<div class="mini-snapshot-ui">
|
||||
<div class="mini-menu-rect"></div>
|
||||
<div class="mini-menu-rect" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="fake-input">
|
||||
<span v-if="stepInt < 5" class="placeholder"
|
||||
>Message ChatGPT...</span
|
||||
>
|
||||
<span v-else class="typing-text"
|
||||
>{{ typedText
|
||||
}}<span class="cursor" v-if="isTyping">|</span></span
|
||||
>
|
||||
<span
|
||||
v-if="stepInt < 5"
|
||||
class="placeholder"
|
||||
>Message ChatGPT...</span>
|
||||
<span
|
||||
v-else
|
||||
class="typing-text"
|
||||
>{{ typedText
|
||||
}}<span
|
||||
v-if="isTyping"
|
||||
class="cursor"
|
||||
>|</span></span>
|
||||
</div>
|
||||
<button
|
||||
class="send-btn"
|
||||
@@ -240,7 +314,11 @@
|
||||
</div>
|
||||
|
||||
<!-- 全局重置按钮 -->
|
||||
<button class="reset-btn" v-if="step === 'finished'" @click="reset">
|
||||
<button
|
||||
v-if="step === 'finished'"
|
||||
class="reset-btn"
|
||||
@click="reset"
|
||||
>
|
||||
🔄 重播
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -76,7 +76,9 @@ const setScenario = (key) => {
|
||||
<template>
|
||||
<div class="arch-demo">
|
||||
<div class="demo-header">
|
||||
<div class="title">🛠️ IDE 核心机制模拟器</div>
|
||||
<div class="title">
|
||||
🛠️ IDE 核心机制模拟器
|
||||
</div>
|
||||
<div class="subtitle">
|
||||
点击下方标签,体验不同配置下的运行结果,理解为什么缺一不可。
|
||||
</div>
|
||||
@@ -102,26 +104,35 @@ const setScenario = (key) => {
|
||||
|
||||
<div class="diagram-container">
|
||||
<!-- Layer 1: VS Code -->
|
||||
<div class="component vscode" :class="{ dim: activeStep === 'env' }">
|
||||
<div class="comp-label">1. 外壳 (VS Code)</div>
|
||||
<div
|
||||
class="component vscode"
|
||||
:class="{ dim: activeStep === 'env' }"
|
||||
>
|
||||
<div class="comp-label">
|
||||
1. 外壳 (VS Code)
|
||||
</div>
|
||||
<div class="editor-window">
|
||||
<div class="file-tab">main.py</div>
|
||||
<div class="file-tab">
|
||||
main.py
|
||||
</div>
|
||||
<div class="code-area">
|
||||
<span style="color: #c586c0">print</span>(<span
|
||||
style="color: #ce9178"
|
||||
>"Hello"</span
|
||||
>)
|
||||
>"Hello"</span>)
|
||||
</div>
|
||||
<button
|
||||
class="run-btn-small"
|
||||
@click="run"
|
||||
:disabled="isRunning"
|
||||
title="点击运行"
|
||||
@click="run"
|
||||
>
|
||||
{{ isRunning ? '...' : '▶ 运行' }}
|
||||
</button>
|
||||
</div>
|
||||
<div class="status-badge error" v-if="activeStep === 'error-editor'">
|
||||
<div
|
||||
v-if="activeStep === 'error-editor'"
|
||||
class="status-badge error"
|
||||
>
|
||||
🚫 不懂怎么运行
|
||||
</div>
|
||||
</div>
|
||||
@@ -135,7 +146,7 @@ const setScenario = (key) => {
|
||||
activeStep
|
||||
)
|
||||
}"
|
||||
></div>
|
||||
/>
|
||||
<div
|
||||
class="arrow-tip"
|
||||
:class="{
|
||||
@@ -156,21 +167,33 @@ const setScenario = (key) => {
|
||||
active: activeStep === 'extension'
|
||||
}"
|
||||
>
|
||||
<div class="comp-label">2. 中介 (插件)</div>
|
||||
<div class="comp-label">
|
||||
2. 中介 (插件)
|
||||
</div>
|
||||
<div class="comp-box">
|
||||
<div v-if="currentScenario === 'editor'" class="missing-content">
|
||||
<div
|
||||
v-if="currentScenario === 'editor'"
|
||||
class="missing-content"
|
||||
>
|
||||
<span class="icon">❌</span> 未安装插件
|
||||
</div>
|
||||
<div v-else class="active-content">
|
||||
<div class="icon">🧩</div>
|
||||
<div class="text">Python 插件</div>
|
||||
<div
|
||||
v-else
|
||||
class="active-content"
|
||||
>
|
||||
<div class="icon">
|
||||
🧩
|
||||
</div>
|
||||
<div class="text">
|
||||
Python 插件
|
||||
</div>
|
||||
<div
|
||||
class="action"
|
||||
v-if="
|
||||
activeStep === 'extension' ||
|
||||
activeStep === 'env' ||
|
||||
activeStep === 'error-env'
|
||||
activeStep === 'env' ||
|
||||
activeStep === 'error-env'
|
||||
"
|
||||
class="action"
|
||||
>
|
||||
生成指令: <code>python main.py</code>
|
||||
</div>
|
||||
@@ -183,7 +206,7 @@ const setScenario = (key) => {
|
||||
<div
|
||||
class="line"
|
||||
:class="{ active: ['env', 'result'].includes(activeStep) }"
|
||||
></div>
|
||||
/>
|
||||
<div
|
||||
class="arrow-tip"
|
||||
:class="{ active: ['env', 'result'].includes(activeStep) }"
|
||||
@@ -200,23 +223,44 @@ const setScenario = (key) => {
|
||||
active: activeStep === 'env'
|
||||
}"
|
||||
>
|
||||
<div class="comp-label">3. 引擎 (环境)</div>
|
||||
<div class="comp-label">
|
||||
3. 引擎 (环境)
|
||||
</div>
|
||||
<div class="comp-box">
|
||||
<div v-if="currentScenario !== 'full'" class="missing-content">
|
||||
<div
|
||||
v-if="currentScenario !== 'full'"
|
||||
class="missing-content"
|
||||
>
|
||||
<span class="icon">❌</span> 未安装环境
|
||||
</div>
|
||||
<div v-else class="active-content">
|
||||
<div class="icon">⚙️</div>
|
||||
<div class="text">Python 解释器</div>
|
||||
<div class="action" v-if="activeStep === 'env'">
|
||||
<div
|
||||
v-else
|
||||
class="active-content"
|
||||
>
|
||||
<div class="icon">
|
||||
⚙️
|
||||
</div>
|
||||
<div class="text">
|
||||
Python 解释器
|
||||
</div>
|
||||
<div
|
||||
v-if="activeStep === 'env'"
|
||||
class="action"
|
||||
>
|
||||
<span class="spin">⚙️</span> 正在计算...
|
||||
</div>
|
||||
<div class="action success" v-if="activeStep === 'result'">
|
||||
<div
|
||||
v-if="activeStep === 'result'"
|
||||
class="action success"
|
||||
>
|
||||
✅ 计算完成
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="status-badge error" v-if="activeStep === 'error-env'">
|
||||
<div
|
||||
v-if="activeStep === 'error-env'"
|
||||
class="status-badge error"
|
||||
>
|
||||
🚫 找不到程序
|
||||
</div>
|
||||
</div>
|
||||
@@ -236,19 +280,22 @@ const setScenario = (key) => {
|
||||
>
|
||||
{{ l }}
|
||||
</div>
|
||||
<div v-if="logs.length === 0" class="placeholder">
|
||||
<div
|
||||
v-if="logs.length === 0"
|
||||
class="placeholder"
|
||||
>
|
||||
点击上方“运行”按钮开始...
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="!isRunning && logs.length > 0"
|
||||
class="result-bar"
|
||||
:class="{
|
||||
success: scenarios[currentScenario].result.includes('成功'),
|
||||
error: !scenarios[currentScenario].result.includes('成功')
|
||||
}"
|
||||
v-if="!isRunning && logs.length > 0"
|
||||
>
|
||||
{{ scenarios[currentScenario].result }}
|
||||
</div>
|
||||
|
||||
@@ -598,21 +598,29 @@ onUnmounted(() => {
|
||||
<div class="demo-wrapper">
|
||||
<!-- External Controls -->
|
||||
<div class="demo-controls">
|
||||
<h3 class="demo-title">虚拟 IDE 交互演示</h3>
|
||||
<h3 class="demo-title">
|
||||
虚拟 IDE 交互演示
|
||||
</h3>
|
||||
|
||||
<div class="tour-controls" v-if="!isAutoPlaying">
|
||||
<div
|
||||
v-if="!isAutoPlaying"
|
||||
class="tour-controls"
|
||||
>
|
||||
<!-- Custom Select -->
|
||||
<div
|
||||
v-click-outside="closeSelect"
|
||||
class="custom-select"
|
||||
:class="{ open: selectOpen }"
|
||||
@click="selectOpen = !selectOpen"
|
||||
v-click-outside="closeSelect"
|
||||
>
|
||||
<div class="select-trigger">
|
||||
<span>{{ currentTourLabel }}</span>
|
||||
<span class="arrow">▼</span>
|
||||
</div>
|
||||
<div class="select-options" v-if="selectOpen">
|
||||
<div
|
||||
v-if="selectOpen"
|
||||
class="select-options"
|
||||
>
|
||||
<div
|
||||
v-for="opt in tourOptions"
|
||||
:key="opt.value"
|
||||
@@ -625,9 +633,20 @@ onUnmounted(() => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button class="tour-btn" @click="startTour">▶ 开始自动导览</button>
|
||||
<button
|
||||
class="tour-btn"
|
||||
@click="startTour"
|
||||
>
|
||||
▶ 开始自动导览
|
||||
</button>
|
||||
</div>
|
||||
<button class="tour-btn stop" @click="stopTour" v-else>■ 停止演示</button>
|
||||
<button
|
||||
v-else
|
||||
class="tour-btn stop"
|
||||
@click="stopTour"
|
||||
>
|
||||
■ 停止演示
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Info Bar (Text Only) -->
|
||||
@@ -638,11 +657,14 @@ onUnmounted(() => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="vscode-mock" ref="vscodeMockRef">
|
||||
<div
|
||||
ref="vscodeMockRef"
|
||||
class="vscode-mock"
|
||||
>
|
||||
<!-- Virtual Cursor -->
|
||||
<div
|
||||
class="virtual-cursor"
|
||||
v-if="cursorVisible"
|
||||
class="virtual-cursor"
|
||||
:style="{ transform: `translate(${cursorX}px, ${cursorY}px)` }"
|
||||
>
|
||||
<svg
|
||||
@@ -662,10 +684,10 @@ onUnmounted(() => {
|
||||
|
||||
<!-- Highlight Box for Auto Tour -->
|
||||
<div
|
||||
class="highlight-box"
|
||||
v-if="highlightVisible"
|
||||
class="highlight-box"
|
||||
:style="highlightStyle"
|
||||
></div>
|
||||
/>
|
||||
|
||||
<!-- Combined Title Bar -->
|
||||
<div
|
||||
@@ -686,8 +708,14 @@ onUnmounted(() => {
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path d="M2 12L7 2L22 12L7 22L2 12Z" fill="#007ACC" />
|
||||
<path d="M17 12L7 5V19L17 12Z" fill="white" />
|
||||
<path
|
||||
d="M2 12L7 2L22 12L7 22L2 12Z"
|
||||
fill="#007ACC"
|
||||
/>
|
||||
<path
|
||||
d="M17 12L7 5V19L17 12Z"
|
||||
fill="white"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div
|
||||
@@ -707,7 +735,10 @@ onUnmounted(() => {
|
||||
>
|
||||
{{ name }}
|
||||
</span>
|
||||
<div v-if="activeMenu === name" class="menu-dropdown">
|
||||
<div
|
||||
v-if="activeMenu === name"
|
||||
class="menu-dropdown"
|
||||
>
|
||||
<div
|
||||
v-for="item in items"
|
||||
:key="item.label"
|
||||
@@ -750,8 +781,8 @@ onUnmounted(() => {
|
||||
>
|
||||
<span
|
||||
class="layout-icon"
|
||||
@click="toggleSidebarView(activeSidebarView)"
|
||||
title="Toggle Sidebar"
|
||||
@click="toggleSidebarView(activeSidebarView)"
|
||||
>
|
||||
<svg
|
||||
width="14"
|
||||
@@ -763,7 +794,11 @@ onUnmounted(() => {
|
||||
<path d="M3 3v10h3V3H3z" />
|
||||
</svg>
|
||||
</span>
|
||||
<span class="layout-icon" @click="togglePanel" title="Toggle Panel">
|
||||
<span
|
||||
class="layout-icon"
|
||||
title="Toggle Panel"
|
||||
@click="togglePanel"
|
||||
>
|
||||
<svg
|
||||
width="14"
|
||||
height="14"
|
||||
@@ -1072,19 +1107,24 @@ onUnmounted(() => {
|
||||
|
||||
<!-- Sidebar -->
|
||||
<div
|
||||
class="sidebar"
|
||||
v-show="sidebarVisible"
|
||||
class="sidebar"
|
||||
@mouseenter.stop="showInfo('侧边栏:详细内容')"
|
||||
@mouseleave="clearInfo"
|
||||
>
|
||||
<div v-if="activeSidebarView === 'EXPLORER'" class="sidebar-content">
|
||||
<div
|
||||
v-if="activeSidebarView === 'EXPLORER'"
|
||||
class="sidebar-content"
|
||||
>
|
||||
<div class="sidebar-header">
|
||||
<span>EXPLORER</span>
|
||||
<span class="sidebar-dots">•••</span>
|
||||
</div>
|
||||
|
||||
<div class="sidebar-section expanded">
|
||||
<div class="section-header">▼ OPEN EDITORS</div>
|
||||
<div class="section-header">
|
||||
▼ OPEN EDITORS
|
||||
</div>
|
||||
<div class="file-list">
|
||||
<div
|
||||
v-if="activeFile.language !== 'welcome'"
|
||||
@@ -1095,41 +1135,49 @@ onUnmounted(() => {
|
||||
<span class="file-name">{{ activeFile.name }}</span>
|
||||
<span class="unsaved-dot">●</span>
|
||||
</div>
|
||||
<div v-else class="empty-list-item">No open editors</div>
|
||||
<div
|
||||
v-else
|
||||
class="empty-list-item"
|
||||
>
|
||||
No open editors
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sidebar-section expanded">
|
||||
<div class="section-header">▼ PYEVAL</div>
|
||||
<div class="section-header">
|
||||
▼ PYEVAL
|
||||
</div>
|
||||
<div class="file-list">
|
||||
<div
|
||||
v-for="(file, index) in files"
|
||||
:key="file.name"
|
||||
v-show="!file.fixed"
|
||||
:key="file.name"
|
||||
class="file-item"
|
||||
:class="{ active: index === activeFileIndex }"
|
||||
@click="selectFile(index)"
|
||||
>
|
||||
<span class="file-icon">
|
||||
<span v-if="file.language === 'html'" style="color: #e34c26"
|
||||
>📄</span
|
||||
>
|
||||
<span
|
||||
v-if="file.language === 'html'"
|
||||
style="color: #e34c26"
|
||||
>📄</span>
|
||||
<span
|
||||
v-else-if="file.language === 'css'"
|
||||
style="color: #563d7c"
|
||||
>🎨</span
|
||||
>
|
||||
>🎨</span>
|
||||
<span
|
||||
v-else-if="file.language === 'python'"
|
||||
style="color: #3776ab"
|
||||
>🐍</span
|
||||
>
|
||||
>🐍</span>
|
||||
<span
|
||||
v-else-if="file.language === 'markdown'"
|
||||
style="color: #42a5f5"
|
||||
>📝</span
|
||||
>
|
||||
<span v-else style="color: #f1e05a">JS</span>
|
||||
>📝</span>
|
||||
<span
|
||||
v-else
|
||||
style="color: #f1e05a"
|
||||
>JS</span>
|
||||
</span>
|
||||
<span class="file-name">{{ file.name }}</span>
|
||||
</div>
|
||||
@@ -1151,25 +1199,30 @@ onUnmounted(() => {
|
||||
placeholder="Search Extensions in Marketplace"
|
||||
:value="searchQuery"
|
||||
readonly
|
||||
/>
|
||||
>
|
||||
</div>
|
||||
<div class="sidebar-section expanded">
|
||||
<div class="section-header">▼ POPULAR</div>
|
||||
<div class="section-header">
|
||||
▼ POPULAR
|
||||
</div>
|
||||
<div class="extension-list">
|
||||
<div
|
||||
v-for="ext in filteredExtensions"
|
||||
:key="ext.id"
|
||||
class="extension-item"
|
||||
>
|
||||
<div class="extension-icon"></div>
|
||||
<div class="extension-icon" />
|
||||
<div class="extension-info">
|
||||
<div class="extension-name">
|
||||
{{ ext.name }}
|
||||
<span v-if="ext.installed" class="installed-badge"
|
||||
>✔</span
|
||||
>
|
||||
<span
|
||||
v-if="ext.installed"
|
||||
class="installed-badge"
|
||||
>✔</span>
|
||||
</div>
|
||||
<div class="extension-desc">
|
||||
{{ ext.description }}
|
||||
</div>
|
||||
<div class="extension-desc">{{ ext.description }}</div>
|
||||
<div class="extension-actions">
|
||||
<button
|
||||
class="install-btn"
|
||||
@@ -1216,30 +1269,40 @@ onUnmounted(() => {
|
||||
<span
|
||||
v-else-if="file.language === 'python'"
|
||||
style="color: #3776ab"
|
||||
>🐍</span
|
||||
>
|
||||
>🐍</span>
|
||||
<span
|
||||
v-else-if="file.language === 'markdown'"
|
||||
style="color: #42a5f5"
|
||||
>📝</span
|
||||
>
|
||||
>📝</span>
|
||||
<span v-else>📄</span>
|
||||
</span>
|
||||
<span class="tab-name">{{ file.name }}</span>
|
||||
<span class="close-tab" @click.stop="closeTab(index)">×</span>
|
||||
<span
|
||||
class="close-tab"
|
||||
@click.stop="closeTab(index)"
|
||||
>×</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab-actions">
|
||||
<span class="action-btn" title="Open Changes">🔃</span>
|
||||
<span class="action-btn" title="Split Editor">◫</span>
|
||||
<span class="action-btn" title="More Actions">•••</span>
|
||||
<span
|
||||
class="action-btn"
|
||||
title="Open Changes"
|
||||
>🔃</span>
|
||||
<span
|
||||
class="action-btn"
|
||||
title="Split Editor"
|
||||
>◫</span>
|
||||
<span
|
||||
class="action-btn"
|
||||
title="More Actions"
|
||||
>•••</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Breadcrumbs (Hidden for Welcome) -->
|
||||
<div
|
||||
class="breadcrumbs"
|
||||
v-if="activeFile.language !== 'welcome'"
|
||||
class="breadcrumbs"
|
||||
@mouseenter.stop="showInfo('路径导航:文件路径')"
|
||||
@mouseleave="clearInfo"
|
||||
>
|
||||
@@ -1257,13 +1320,15 @@ onUnmounted(() => {
|
||||
>
|
||||
<!-- Welcome Content -->
|
||||
<div
|
||||
class="welcome-content"
|
||||
v-if="activeFile.language === 'welcome'"
|
||||
class="welcome-content"
|
||||
>
|
||||
<div class="welcome-container">
|
||||
<div class="welcome-header">
|
||||
<h1>Visual Studio Code</h1>
|
||||
<p class="subtitle">Editing evolved</p>
|
||||
<p class="subtitle">
|
||||
Editing evolved
|
||||
</p>
|
||||
</div>
|
||||
<div class="welcome-grid">
|
||||
<div class="welcome-column">
|
||||
@@ -1284,11 +1349,11 @@ onUnmounted(() => {
|
||||
<span class="action-icon">🌿</span>
|
||||
<span class="action-text">Clone Git Repository...</span>
|
||||
</div>
|
||||
<h3 class="mt-4">Recent</h3>
|
||||
<h3 class="mt-4">
|
||||
Recent
|
||||
</h3>
|
||||
<div class="recent-item">
|
||||
<span class="recent-path"
|
||||
>pyeval/pyeval_expression.py</span
|
||||
>
|
||||
<span class="recent-path">pyeval/pyeval_expression.py</span>
|
||||
<span class="recent-detail">~/projects/pyeval</span>
|
||||
</div>
|
||||
<div class="recent-item">
|
||||
@@ -1299,7 +1364,9 @@ onUnmounted(() => {
|
||||
<div class="welcome-column">
|
||||
<h3>Walkthroughs</h3>
|
||||
<div class="walkthrough-card">
|
||||
<div class="walkthrough-icon">⭐</div>
|
||||
<div class="walkthrough-icon">
|
||||
⭐
|
||||
</div>
|
||||
<div class="walkthrough-info">
|
||||
<div class="walkthrough-title">
|
||||
Get Started with VS Code
|
||||
@@ -1311,7 +1378,9 @@ onUnmounted(() => {
|
||||
</div>
|
||||
</div>
|
||||
<div class="walkthrough-card">
|
||||
<div class="walkthrough-icon">🐍</div>
|
||||
<div class="walkthrough-icon">
|
||||
🐍
|
||||
</div>
|
||||
<div class="walkthrough-info">
|
||||
<div class="walkthrough-title">
|
||||
Get Started with Python
|
||||
@@ -1327,9 +1396,17 @@ onUnmounted(() => {
|
||||
</div>
|
||||
|
||||
<!-- Code Content -->
|
||||
<div class="code-content" v-else>
|
||||
<div
|
||||
v-else
|
||||
class="code-content"
|
||||
>
|
||||
<div class="line-numbers">
|
||||
<div v-for="n in 20" :key="n">{{ n }}</div>
|
||||
<div
|
||||
v-for="n in 20"
|
||||
:key="n"
|
||||
>
|
||||
{{ n }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="code-wrapper">
|
||||
<pre><code>{{ activeFile.content }}</code></pre>
|
||||
@@ -1340,7 +1417,7 @@ onUnmounted(() => {
|
||||
@mouseenter.stop="showInfo('缩略图:快速跳转')"
|
||||
@mouseleave="clearInfo"
|
||||
>
|
||||
<div class="minimap-slider"></div>
|
||||
<div class="minimap-slider" />
|
||||
<div
|
||||
v-for="n in 40"
|
||||
:key="n"
|
||||
@@ -1349,7 +1426,7 @@ onUnmounted(() => {
|
||||
width: Math.random() * 80 + '%',
|
||||
opacity: Math.random() * 0.5 + 0.3
|
||||
}"
|
||||
></div>
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1358,8 +1435,8 @@ onUnmounted(() => {
|
||||
|
||||
<!-- Bottom Panel -->
|
||||
<div
|
||||
class="bottom-panel"
|
||||
v-if="panelVisible"
|
||||
class="bottom-panel"
|
||||
@mouseenter.stop="showInfo('底部面板:集成工具')"
|
||||
@mouseleave="clearInfo"
|
||||
>
|
||||
@@ -1371,32 +1448,28 @@ onUnmounted(() => {
|
||||
@click="activePanel = 'PROBLEMS'"
|
||||
@mouseenter.stop="showInfo('问题面板:错误警告')"
|
||||
@mouseleave="clearInfo"
|
||||
>PROBLEMS <span class="badge">0</span></span
|
||||
>
|
||||
>PROBLEMS <span class="badge">0</span></span>
|
||||
<span
|
||||
class="panel-tab"
|
||||
:class="{ active: activePanel === 'OUTPUT' }"
|
||||
@click="activePanel = 'OUTPUT'"
|
||||
@mouseenter.stop="showInfo('输出面板:日志')"
|
||||
@mouseleave="clearInfo"
|
||||
>OUTPUT</span
|
||||
>
|
||||
>OUTPUT</span>
|
||||
<span
|
||||
class="panel-tab"
|
||||
:class="{ active: activePanel === 'DEBUG CONSOLE' }"
|
||||
@click="activePanel = 'DEBUG CONSOLE'"
|
||||
@mouseenter.stop="showInfo('调试控制台')"
|
||||
@mouseleave="clearInfo"
|
||||
>DEBUG CONSOLE</span
|
||||
>
|
||||
>DEBUG CONSOLE</span>
|
||||
<span
|
||||
class="panel-tab"
|
||||
:class="{ active: activePanel === 'TERMINAL' }"
|
||||
@click="activePanel = 'TERMINAL'"
|
||||
@mouseenter.stop="showInfo('终端:命令行')"
|
||||
@mouseleave="clearInfo"
|
||||
>TERMINAL</span
|
||||
>
|
||||
>TERMINAL</span>
|
||||
</div>
|
||||
<div
|
||||
class="panel-actions"
|
||||
@@ -1405,19 +1478,32 @@ onUnmounted(() => {
|
||||
>
|
||||
<span class="action-btn">➕</span>
|
||||
<span class="action-btn">🗑️</span>
|
||||
<span class="action-btn" @click="panelVisible = false">×</span>
|
||||
<span
|
||||
class="action-btn"
|
||||
@click="panelVisible = false"
|
||||
>×</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div v-if="activePanel === 'TERMINAL'" class="terminal-content">
|
||||
<div v-for="(line, i) in terminalLines" :key="i" :class="line.type">
|
||||
<div
|
||||
v-if="activePanel === 'TERMINAL'"
|
||||
class="terminal-content"
|
||||
>
|
||||
<div
|
||||
v-for="(line, i) in terminalLines"
|
||||
:key="i"
|
||||
:class="line.type"
|
||||
>
|
||||
{{ line.text }}
|
||||
</div>
|
||||
<div class="cursor-line">
|
||||
➜ pyeval git:(master) ✗ <span class="cursor">_</span>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="empty-panel">
|
||||
<div
|
||||
v-else
|
||||
class="empty-panel"
|
||||
>
|
||||
No content to display in {{ activePanel }}.
|
||||
</div>
|
||||
</div>
|
||||
@@ -1431,9 +1517,7 @@ onUnmounted(() => {
|
||||
>
|
||||
<div class="status-left">
|
||||
<span class="status-item"><span class="icon">🔃</span> master*</span>
|
||||
<span class="status-item"
|
||||
><span class="icon">ⓧ</span> 0 <span class="icon">⚠</span> 0</span
|
||||
>
|
||||
<span class="status-item"><span class="icon">ⓧ</span> 0 <span class="icon">⚠</span> 0</span>
|
||||
</div>
|
||||
<div class="status-right">
|
||||
<span class="status-item">Ln 119, Col 71</span>
|
||||
|
||||
Reference in New Issue
Block a user