mirror of
https://github.com/QwenLM/qwen-code.git
synced 2025-12-22 17:57:46 +00:00
chore(vscode-ide-companion): wip
This commit is contained in:
@@ -69,6 +69,7 @@ export const App: React.FC = () => {
|
||||
} | null>(null);
|
||||
const [planEntries, setPlanEntries] = useState<PlanEntry[]>([]);
|
||||
const [isAuthenticated, setIsAuthenticated] = useState<boolean | null>(null);
|
||||
const [isLoading, setIsLoading] = useState<boolean>(true); // Track if we're still initializing/loading
|
||||
const messagesEndRef = useRef<HTMLDivElement>(
|
||||
null,
|
||||
) as React.RefObject<HTMLDivElement>;
|
||||
@@ -360,6 +361,14 @@ export const App: React.FC = () => {
|
||||
completedToolCalls,
|
||||
]);
|
||||
|
||||
// Set loading state to false after initial mount and when we have authentication info
|
||||
useEffect(() => {
|
||||
// If we have determined authentication status, we're done loading
|
||||
if (isAuthenticated !== null) {
|
||||
setIsLoading(false);
|
||||
}
|
||||
}, [isAuthenticated]);
|
||||
|
||||
// Handle permission response
|
||||
const handlePermissionResponse = useCallback(
|
||||
(optionId: string) => {
|
||||
@@ -666,7 +675,19 @@ export const App: React.FC = () => {
|
||||
allMessages.length > 0;
|
||||
|
||||
return (
|
||||
<div className="chat-container">
|
||||
<div className="chat-container relative">
|
||||
{/* Top-level loading overlay */}
|
||||
{isLoading && (
|
||||
<div className="bg-background/80 absolute inset-0 z-50 flex items-center justify-center backdrop-blur-sm">
|
||||
<div className="text-center">
|
||||
<div className="border-primary mx-auto mb-2 h-8 w-8 animate-spin rounded-full border-b-2"></div>
|
||||
<p className="text-muted-foreground text-sm">
|
||||
Preparing Qwen Code...
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<SessionSelector
|
||||
visible={sessionManagement.showSessionSelector}
|
||||
sessions={sessionManagement.filteredSessions}
|
||||
@@ -693,7 +714,7 @@ export const App: React.FC = () => {
|
||||
ref={messagesContainerRef}
|
||||
className="chat-messages messages-container flex-1 overflow-y-auto overflow-x-hidden pt-5 pr-5 pl-5 pb-[140px] 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-[8px] [&>*]:flex-col [&>*]:relative [&>*]:animate-[fadeIn_0.2s_ease-in]"
|
||||
>
|
||||
{!hasContent ? (
|
||||
{!hasContent && !isLoading ? (
|
||||
isAuthenticated === false ? (
|
||||
<Onboarding
|
||||
onLogin={() => {
|
||||
|
||||
@@ -13,9 +13,11 @@ import { PanelManager } from '../webview/PanelManager.js';
|
||||
import { MessageHandler } from '../webview/MessageHandler.js';
|
||||
import { WebViewContent } from '../webview/WebViewContent.js';
|
||||
import { CliInstaller } from '../cli/cliInstaller.js';
|
||||
import { CliVersionChecker } from '../cli/cliVersionChecker.js';
|
||||
import { getFileName } from './utils/webviewUtils.js';
|
||||
import { type ApprovalModeValue } from '../types/approvalModeValueTypes.js';
|
||||
import { isAuthenticationRequiredError } from '../utils/authErrors.js';
|
||||
import { dismissAuthenticateUpdate } from '../utils/authNotificationHandler.js';
|
||||
|
||||
/**
|
||||
* WebView Provider Class
|
||||
@@ -46,7 +48,7 @@ export class WebViewProvider {
|
||||
private currentModeId: ApprovalModeValue | null = null;
|
||||
|
||||
constructor(
|
||||
context: vscode.ExtensionContext,
|
||||
private context: vscode.ExtensionContext,
|
||||
private extensionUri: vscode.Uri,
|
||||
) {
|
||||
this.agentManager = new QwenAgentManager();
|
||||
@@ -619,6 +621,21 @@ export class WebViewProvider {
|
||||
console.log('[WebViewProvider] CLI path:', cliDetection.cliPath);
|
||||
console.log('[WebViewProvider] CLI version:', cliDetection.version);
|
||||
|
||||
// Perform version check with throttled notifications
|
||||
const versionChecker = CliVersionChecker.getInstance(this.context);
|
||||
const versionCheckResult = await versionChecker.checkCliVersion(false); // Silent check to avoid popup spam
|
||||
|
||||
if (!versionCheckResult.isSupported) {
|
||||
console.log(
|
||||
'[WebViewProvider] Qwen CLI version is outdated or unsupported',
|
||||
versionCheckResult,
|
||||
);
|
||||
// Log to output channel instead of showing popup
|
||||
console.warn(
|
||||
`Qwen Code CLI version issue: Installed=${versionCheckResult.version || 'unknown'}, Supported=${versionCheckResult.isSupported}`,
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
console.log('[WebViewProvider] Connecting to agent...');
|
||||
|
||||
@@ -630,6 +647,22 @@ export class WebViewProvider {
|
||||
);
|
||||
console.log('[WebViewProvider] Agent connected successfully');
|
||||
this.agentInitialized = true;
|
||||
|
||||
// If authentication is required and autoAuthenticate is false,
|
||||
// send authState message and return without creating session
|
||||
if (connectResult.requiresAuth && !autoAuthenticate) {
|
||||
console.log(
|
||||
'[WebViewProvider] Authentication required but auto-auth disabled, sending authState and returning',
|
||||
);
|
||||
this.sendMessageToWebView({
|
||||
type: 'authState',
|
||||
data: { authenticated: false },
|
||||
});
|
||||
// Initialize empty conversation to allow browsing history
|
||||
await this.initializeEmptyConversation();
|
||||
return;
|
||||
}
|
||||
|
||||
if (connectResult.requiresAuth) {
|
||||
this.sendMessageToWebView({
|
||||
type: 'authState',
|
||||
@@ -641,6 +674,9 @@ export class WebViewProvider {
|
||||
const sessionReady = await this.loadCurrentSessionMessages(options);
|
||||
|
||||
if (sessionReady) {
|
||||
// Dismiss any authentication notifications
|
||||
dismissAuthenticateUpdate();
|
||||
|
||||
// Notify webview that agent is connected
|
||||
this.sendMessageToWebView({
|
||||
type: 'agentConnected',
|
||||
@@ -715,6 +751,9 @@ export class WebViewProvider {
|
||||
'[WebViewProvider] Force re-login completed successfully',
|
||||
);
|
||||
|
||||
// Dismiss any authentication notifications
|
||||
dismissAuthenticateUpdate();
|
||||
|
||||
// Send success notification to WebView
|
||||
this.sendMessageToWebView({
|
||||
type: 'loginSuccess',
|
||||
@@ -769,6 +808,9 @@ export class WebViewProvider {
|
||||
'[WebViewProvider] Connection refresh completed successfully',
|
||||
);
|
||||
|
||||
// Dismiss any authentication notifications
|
||||
dismissAuthenticateUpdate();
|
||||
|
||||
// Notify webview that agent is connected after refresh
|
||||
this.sendMessageToWebView({
|
||||
type: 'agentConnected',
|
||||
|
||||
@@ -27,24 +27,33 @@ export const EmptyState: React.FC<EmptyStateProps> = ({
|
||||
|
||||
return (
|
||||
<div className="flex flex-col items-center justify-center h-full p-5 md:p-10">
|
||||
{/* Loading overlay */}
|
||||
{loadingMessage && (
|
||||
<div className="bg-background/80 absolute inset-0 z-50 flex items-center justify-center backdrop-blur-sm">
|
||||
<div className="text-center">
|
||||
<div className="border-primary mx-auto mb-2 h-8 w-8 animate-spin rounded-full border-b-2"></div>
|
||||
<p className="text-muted-foreground text-sm">{loadingMessage}</p>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="flex flex-col items-center gap-8 w-full">
|
||||
{/* Qwen Logo */}
|
||||
<div className="flex flex-col items-center gap-6">
|
||||
<img
|
||||
src={iconUri}
|
||||
alt="Qwen Logo"
|
||||
className="w-[60px] h-[60px] object-contain"
|
||||
/>
|
||||
{iconUri ? (
|
||||
<img
|
||||
src={iconUri}
|
||||
alt="Qwen Logo"
|
||||
className="w-[60px] h-[60px] object-contain"
|
||||
onError={(e) => {
|
||||
// Fallback to a div with text if image fails to load
|
||||
const target = e.target as HTMLImageElement;
|
||||
target.style.display = 'none';
|
||||
const parent = target.parentElement;
|
||||
if (parent) {
|
||||
const fallback = document.createElement('div');
|
||||
fallback.className =
|
||||
'w-[60px] h-[60px] flex items-center justify-center text-2xl font-bold';
|
||||
fallback.textContent = 'Q';
|
||||
parent.appendChild(fallback);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<div className="w-[60px] h-[60px] flex items-center justify-center text-2xl font-bold bg-gray-200 rounded">
|
||||
Q
|
||||
</div>
|
||||
)}
|
||||
<div className="text-center">
|
||||
<div className="text-[15px] text-app-primary-foreground leading-normal font-normal max-w-[400px]">
|
||||
{description}
|
||||
|
||||
Reference in New Issue
Block a user