mirror of
https://github.com/QwenLM/qwen-code.git
synced 2025-12-19 09:33:53 +00:00
wip(vscode-ide-companion): timelint
This commit is contained in:
@@ -477,7 +477,7 @@ export const App: React.FC = () => {
|
||||
|
||||
<div
|
||||
ref={messagesContainerRef}
|
||||
className="chat-messages flex-1 overflow-y-auto overflow-x-hidden pt-5 pr-5 pl-5 pb-[120px] flex flex-col relative min-w-0 focus:outline-none [&::-webkit-scrollbar]:w-2 [&::-webkit-scrollbar-track]:bg-transparent [&::-webkit-scrollbar-thumb]:bg-white/20 [&::-webkit-scrollbar-thumb]:rounded-sm [&::-webkit-scrollbar-thumb:hover]:bg-white/30 [&>*]:flex [&>*]:gap-0 [&>*]:items-start [&>*]:text-left [&>*]:py-2 [&>*:not(:last-child)]:mb-[10px] [&>.message-item]:px-0 [&>.message-item]:py-0 [&>*]:flex-col [&>*]:relative [&>*]:animate-[fadeIn_0.2s_ease-in]"
|
||||
className="chat-messages flex-1 overflow-y-auto overflow-x-hidden pt-5 pr-5 pl-5 pb-[120px] flex flex-col relative min-w-0 focus:outline-none [&::-webkit-scrollbar]:w-2 [&::-webkit-scrollbar-track]:bg-transparent [&::-webkit-scrollbar-thumb]:bg-white/20 [&::-webkit-scrollbar-thumb]:rounded-sm [&::-webkit-scrollbar-thumb:hover]:bg-white/30 [&>*]:flex [&>*]:gap-0 [&>*]:items-start [&>*]:text-left [&>*]:py-2 [&>*:not(:last-child)]:pb-[10px] [&>.message-item]:px-0 [&>.message-item]:py-0 [&>*]:flex-col [&>*]:relative [&>*]:animate-[fadeIn_0.2s_ease-in]"
|
||||
style={{ backgroundColor: 'var(--app-primary-background)' }}
|
||||
>
|
||||
{!hasContent ? (
|
||||
|
||||
@@ -155,14 +155,7 @@ export const InProgressToolCall: React.FC<InProgressToolCallProps> = ({
|
||||
|
||||
return (
|
||||
<div className="relative py-2 toolcall-container">
|
||||
<div className="flex items-center gap-2 mb-1 relative">
|
||||
{/* Pulsing bullet dot (Claude-style), vertically centered with header row */}
|
||||
<span
|
||||
aria-hidden
|
||||
className="absolute -left-[20px] top-1/2 -translate-y-1/2 text-[10px] leading-none text-[#e1c08d] animate-[pulse_1.5s_ease-in-out_infinite]"
|
||||
>
|
||||
●
|
||||
</span>
|
||||
<div className="flex items-center gap-2 mb-1 relative before:content-['\25cf'] before:absolute before:left-[-22px] before:top-1/2 before:-translate-y-1/2 before:text-[10px] before:leading-none before:text-[#e1c08d] before:animate-pulse-slow">
|
||||
<span className={`text-xs font-medium ${kindColorClass}`}>
|
||||
{kindLabel}
|
||||
</span>
|
||||
|
||||
@@ -58,32 +58,3 @@
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
/* Timeline connector line using ::after pseudo-element */
|
||||
/* Default: full height connector for middle items */
|
||||
.assistant-message-container::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 12px;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 1px;
|
||||
background-color: var(--app-primary-border-color);
|
||||
opacity: 0.4;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
/* First item: connector starts from bullet point position */
|
||||
.assistant-message-container:first-child::after {
|
||||
top: 12px; /* Start from around the bullet point position (8px padding + 4px offset) */
|
||||
}
|
||||
|
||||
/* Last item: connector ends at bullet point position */
|
||||
.assistant-message-container:last-child::after {
|
||||
bottom: 12px; /* End at around the bullet point position */
|
||||
}
|
||||
|
||||
/* First and last are the same item (single item): no connector */
|
||||
.assistant-message-container:first-child:last-child::after {
|
||||
content: none;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
import type React from 'react';
|
||||
import { MessageContent } from '../MessageContent.js';
|
||||
import './AssistantMessage.css';
|
||||
import './SimpleTimeline.css';
|
||||
|
||||
interface AssistantMessageProps {
|
||||
content: string;
|
||||
@@ -55,7 +56,7 @@ export const AssistantMessage: React.FC<AssistantMessageProps> = ({
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`assistant-message-container ${getStatusClass()}`}
|
||||
className={`assistant-message-container simple-timeline-container ${getStatusClass()}`}
|
||||
style={{
|
||||
width: '100%',
|
||||
alignItems: 'flex-start',
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2025 Qwen Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Simplified timeline styles for testing
|
||||
*/
|
||||
|
||||
/* Basic timeline container */
|
||||
.simple-timeline-container {
|
||||
position: relative;
|
||||
padding-left: 30px;
|
||||
padding-top: 8px;
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
|
||||
/* Timeline connector - simple version */
|
||||
.simple-timeline-container::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 12px;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 1px;
|
||||
background-color: var(--app-primary-border-color);
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* First item connector starts lower */
|
||||
.simple-timeline-container:first-child::after {
|
||||
top: 24px;
|
||||
}
|
||||
|
||||
/* Last item connector ends higher */
|
||||
.simple-timeline-container:last-child::after {
|
||||
height: calc(100% - 24px);
|
||||
top: 0;
|
||||
bottom: auto;
|
||||
}
|
||||
|
||||
/* Bullet point */
|
||||
.simple-timeline-container::before {
|
||||
content: '\25cf';
|
||||
position: absolute;
|
||||
left: 8px;
|
||||
padding-top: 2px;
|
||||
font-size: 10px;
|
||||
color: var(--app-secondary-foreground);
|
||||
z-index: 2;
|
||||
}
|
||||
@@ -16,38 +16,33 @@
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
/* Timeline connector line using ::after pseudo-element */
|
||||
/* Default: full height connector for middle items */
|
||||
/* Default timeline connector line */
|
||||
.toolcall-container::after {
|
||||
content: "";
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 12px;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 1px;
|
||||
background-color: var(--app-primary-border-color);
|
||||
opacity: 0.4;
|
||||
z-index: 0;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* First item: connector starts from bullet point position */
|
||||
/* First item: connector starts from status point position */
|
||||
.toolcall-container:first-child::after {
|
||||
top: 12px; /* Start from around the bullet point position (8px padding + 4px offset) */
|
||||
top: 24px;
|
||||
}
|
||||
|
||||
/* Last item: connector ends at bullet point position */
|
||||
/* Last item: connector shows only upper part */
|
||||
.toolcall-container:last-child::after {
|
||||
bottom: 12px; /* End at around the bullet point position */
|
||||
}
|
||||
|
||||
/* First and last are the same item (single item): no connector */
|
||||
.toolcall-container:first-child:last-child::after {
|
||||
content: none;
|
||||
height: calc(100% - 24px);
|
||||
top: 0;
|
||||
bottom: auto;
|
||||
}
|
||||
|
||||
/* Status-specific styles using ::before pseudo-element for bullet points */
|
||||
.toolcall-container.toolcall-status-default::before {
|
||||
content: "\25cf";
|
||||
content: '\25cf';
|
||||
position: absolute;
|
||||
left: 8px;
|
||||
padding-top: 2px;
|
||||
@@ -57,17 +52,16 @@
|
||||
}
|
||||
|
||||
.toolcall-container.toolcall-status-success::before {
|
||||
content: "\25cf";
|
||||
content: '\25cf';
|
||||
position: absolute;
|
||||
left: 8px;
|
||||
padding-top: 2px;
|
||||
font-size: 10px;
|
||||
color: #74c991;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.toolcall-container.toolcall-status-error::before {
|
||||
content: "\25cf";
|
||||
content: '\25cf';
|
||||
position: absolute;
|
||||
left: 8px;
|
||||
padding-top: 2px;
|
||||
@@ -77,7 +71,7 @@
|
||||
}
|
||||
|
||||
.toolcall-container.toolcall-status-warning::before {
|
||||
content: "\25cf";
|
||||
content: '\25cf';
|
||||
position: absolute;
|
||||
left: 8px;
|
||||
padding-top: 2px;
|
||||
@@ -87,7 +81,7 @@
|
||||
}
|
||||
|
||||
.toolcall-container.toolcall-status-loading::before {
|
||||
content: "\25cf";
|
||||
content: '\25cf';
|
||||
position: absolute;
|
||||
left: 8px;
|
||||
padding-top: 2px;
|
||||
@@ -158,4 +152,9 @@
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
/* Flex container with margin bottom */
|
||||
.toolcall-header {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
import type React from 'react';
|
||||
import { FileLink } from '../../ui/FileLink.js';
|
||||
import './LayoutComponents.css';
|
||||
import './SimpleTimeline.css';
|
||||
|
||||
/**
|
||||
* Props for ToolCallContainer - Claude Code style layout
|
||||
@@ -46,7 +47,7 @@ export const ToolCallContainer: React.FC<ToolCallContainerProps> = ({
|
||||
>
|
||||
{/* Timeline connector line using ::after pseudo-element */}
|
||||
<div className="toolcall-content-wrapper flex flex-col gap-1 min-w-0 max-w-full">
|
||||
<div className="flex items-center gap-2 relative min-w-0">
|
||||
<div className="flex items-center gap-2 relative min-w-0 toolcall-header">
|
||||
<span className="text-[14px] leading-none font-bold text-[var(--app-primary-foreground)]">
|
||||
{label}
|
||||
</span>
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2025 Qwen Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Simplified timeline styles for tool calls
|
||||
*/
|
||||
|
||||
/* Basic timeline container */
|
||||
.simple-toolcall-container {
|
||||
position: relative;
|
||||
padding-left: 30px;
|
||||
padding-top: 8px;
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
|
||||
/* Timeline connector - simple version */
|
||||
.simple-toolcall-container::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 12px;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 1px;
|
||||
background-color: var(--app-primary-border-color);
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* First item connector starts lower */
|
||||
.simple-toolcall-container:first-child::after {
|
||||
top: 24px;
|
||||
}
|
||||
|
||||
/* Last item connector ends higher */
|
||||
.simple-toolcall-container:last-child::after {
|
||||
height: calc(100% - 24px);
|
||||
top: 0;
|
||||
bottom: auto;
|
||||
}
|
||||
|
||||
/* Bullet point */
|
||||
.simple-toolcall-container::before {
|
||||
content: '\25cf';
|
||||
position: absolute;
|
||||
left: 8px;
|
||||
padding-top: 2px;
|
||||
font-size: 10px;
|
||||
color: var(--app-secondary-foreground);
|
||||
z-index: 2;
|
||||
}
|
||||
@@ -12,6 +12,8 @@
|
||||
@import '../components/PlanDisplay.css';
|
||||
@import '../components/toolcalls/shared/DiffDisplay.css';
|
||||
@import '../components/messages/AssistantMessage.css';
|
||||
@import '../components/messages/SimpleTimeline.css';
|
||||
@import '../components/toolcalls/shared/SimpleTimeline.css';
|
||||
|
||||
|
||||
/* ===========================
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2025 Qwen Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* CSS Selector Compatibility Test
|
||||
*/
|
||||
|
||||
/* Test 1: Basic first-child and last-child selectors */
|
||||
.test-container:first-child::after {
|
||||
content: "FIRST";
|
||||
color: red;
|
||||
}
|
||||
|
||||
.test-container:last-child::after {
|
||||
content: "LAST";
|
||||
color: blue;
|
||||
}
|
||||
|
||||
.test-container:first-child:last-child::after {
|
||||
content: "ONLY";
|
||||
color: green;
|
||||
}
|
||||
|
||||
/* Test 2: Simple sibling selectors */
|
||||
.test-container + .test-container::before {
|
||||
content: "SIBLING";
|
||||
color: orange;
|
||||
}
|
||||
|
||||
/* Test 3: Not selector */
|
||||
.test-container:not(.special)::after {
|
||||
content: "NOT SPECIAL";
|
||||
color: purple;
|
||||
}
|
||||
@@ -29,9 +29,15 @@ export default {
|
||||
'0%': { opacity: '0', transform: 'translateY(4px)' },
|
||||
'100%': { opacity: '1', transform: 'translateY(0)' },
|
||||
},
|
||||
// Pulse animation for in-progress tool calls
|
||||
'pulse-slow': {
|
||||
'0%, 100%': { opacity: '1' },
|
||||
'50%': { opacity: '0.5' },
|
||||
},
|
||||
},
|
||||
animation: {
|
||||
'completion-menu-enter': 'completion-menu-enter 150ms ease-out both',
|
||||
'pulse-slow': 'pulse-slow 1.5s ease-in-out infinite',
|
||||
},
|
||||
colors: {
|
||||
qwen: {
|
||||
|
||||
Reference in New Issue
Block a user