Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 2 additions & 30 deletions src/vs/workbench/api/browser/mainThreadChatSessions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { IMarkdownString, MarkdownString } from '../../../base/common/htmlConten
import { Disposable, DisposableMap, DisposableStore, IDisposable } from '../../../base/common/lifecycle.js';
import { revive } from '../../../base/common/marshalling.js';
import { IObservable, observableValue, autorun } from '../../../base/common/observable.js';
import { URI, UriComponents } from '../../../base/common/uri.js';
import { localize } from '../../../nls.js';
import { IDialogService } from '../../../platform/dialogs/common/dialogs.js';
import { ILogService } from '../../../platform/log/common/log.js';
Expand Down Expand Up @@ -346,7 +345,7 @@ export class MainThreadChatSessions extends Disposable implements MainThreadChat
return sessions.map(session => ({
...session,
id: session.id,
iconPath: session.iconPath ? this._reviveIconPath(session.iconPath) : undefined,
iconPath: session.iconPath,
tooltip: session.tooltip ? this._reviveTooltip(session.tooltip) : undefined
}));
} catch (error) {
Expand All @@ -364,7 +363,7 @@ export class MainThreadChatSessions extends Disposable implements MainThreadChat
return {
...chatSessionItem,
id: chatSessionItem.id,
iconPath: chatSessionItem.iconPath ? this._reviveIconPath(chatSessionItem.iconPath) : undefined,
iconPath: chatSessionItem.iconPath,
tooltip: chatSessionItem.tooltip ? this._reviveTooltip(chatSessionItem.tooltip) : undefined,
};
} catch (error) {
Expand Down Expand Up @@ -472,33 +471,6 @@ export class MainThreadChatSessions extends Disposable implements MainThreadChat
super.dispose();
}

private _reviveIconPath(
iconPath: UriComponents | { light: UriComponents; dark: UriComponents } | { id: string; color?: { id: string } | undefined })
: IChatSessionItem['iconPath'] {
if (!iconPath) {
return undefined;
}

// Handle ThemeIcon (has id property)
if (typeof iconPath === 'object' && 'id' in iconPath) {
return iconPath; // ThemeIcon doesn't need conversion
}

// handle single URI
if (typeof iconPath === 'object' && 'scheme' in iconPath) {
return URI.revive(iconPath);
}

// Handle light/dark theme icons
if (typeof iconPath === 'object' && ('light' in iconPath && 'dark' in iconPath)) {
return {
light: URI.revive(iconPath.light),
dark: URI.revive(iconPath.dark)
};
}
return undefined;
}

private _reviveTooltip(tooltip: string | IMarkdownString | undefined): string | MarkdownString | undefined {
if (!tooltip) {
return undefined;
Expand Down
1 change: 0 additions & 1 deletion src/vs/workbench/api/common/extHostChatSessions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,6 @@ export class ExtHostChatSessions extends Disposable implements ExtHostChatSessio
return {
id: sessionContent.id,
label: sessionContent.label,
iconPath: sessionContent.iconPath,
description: sessionContent.description,
status: this.convertChatSessionStatus(sessionContent.status),
tooltip: typeConvert.MarkdownString.fromStrict(sessionContent.tooltip),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@ export class ChatSessionsService extends Disposable implements IChatSessionsServ
override: ChatEditorInput.EditorID,
pinned: true,
chatSessionType: type, // This will 'lock' the UI of the new, unattached editor to our chat session type
ignoreInView: true,
};
await editorService.openEditor({
resource: ChatEditorInput.getNewEditorUri(),
Expand Down
38 changes: 20 additions & 18 deletions src/vs/workbench/contrib/chat/browser/chatSessions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -970,6 +970,20 @@ class SessionsRenderer extends Disposable implements ITreeRenderer<IChatSessionI
};
}

statusToIcon(status?: ChatSessionStatus) {
switch (status) {
case ChatSessionStatus.InProgress:
return Codicon.loading;
case ChatSessionStatus.Completed:
return Codicon.pass;
case ChatSessionStatus.Failed:
return Codicon.error;
default:
return Codicon.circleOutline;
}

}

renderElement(element: ITreeNode<IChatSessionItem, FuzzyScore>, index: number, templateData: ISessionTemplateData): void {
const session = element.element;
const sessionWithProvider = session as ChatSessionItemWithProvider;
Expand Down Expand Up @@ -1015,24 +1029,12 @@ class SessionsRenderer extends Disposable implements ITreeRenderer<IChatSessionI
// Handle different icon types
let iconResource: URI | undefined;
let iconTheme: ThemeIcon | undefined;
let iconUri: URI | undefined;

if (session.iconPath) {
if (session.iconPath instanceof URI) {
// Check if it's a data URI - if so, use it as icon option instead of resource
if (session.iconPath.scheme === 'data') {
iconUri = session.iconPath;
} else {
iconResource = session.iconPath;
}
} else if (ThemeIcon.isThemeIcon(session.iconPath)) {
iconTheme = session.iconPath;
} else {
// Handle {light, dark} structure
iconResource = session.iconPath.light;
}
if (!session.iconPath && session.id !== 'show-history') {
iconTheme = this.statusToIcon(session.status);
} else {
iconTheme = session.iconPath;
}
// Apply color styling if specified

if (iconTheme?.color?.id) {
this.applyIconColorStyle(iconTheme.id, iconTheme.color.id);
}
Expand All @@ -1044,7 +1046,7 @@ class SessionsRenderer extends Disposable implements ITreeRenderer<IChatSessionI
resource: iconResource
}, {
fileKind: undefined,
icon: iconTheme || iconUri,
icon: iconTheme,
title: 'tooltip' in session && session.tooltip ?
(typeof session.tooltip === 'string' ? session.tooltip :
isMarkdownString(session.tooltip) ? {
Expand Down
8 changes: 8 additions & 0 deletions src/vs/workbench/contrib/chat/browser/media/chatSessions.css
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,14 @@
overflow: hidden;
}

.chat-sessions-tree-container .chat-session-item .monaco-icon-label::before {
text-align: center;
}

.chat-sessions-tree-container .chat-session-item .monaco-icon-label.codicon-loading::before {
animation: codicon-spin 1.5s steps(30) infinite;
}

/* Timestamp styling - similar to timeline pane */
.chat-sessions-tree-container .chat-session-item .timestamp-container {
margin-left: auto;
Expand Down
6 changes: 1 addition & 5 deletions src/vs/workbench/contrib/chat/common/chatSessionsService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import { CancellationToken } from '../../../../base/common/cancellation.js';
import { Event } from '../../../../base/common/event.js';
import { IObservable } from '../../../../base/common/observable.js';
import { createDecorator } from '../../../../platform/instantiation/common/instantiation.js';
import { URI } from '../../../../base/common/uri.js';
import { ThemeIcon } from '../../../../base/common/themables.js';
import { IChatProgress } from './chatService.js';
import { IChatAgentRequest } from './chatAgents.js';
Expand All @@ -34,10 +33,7 @@ export interface IChatSessionsExtensionPoint {
export interface IChatSessionItem {
id: string;
label: string;
iconPath?: URI | {
light: URI;
dark: URI;
} | ThemeIcon;
iconPath?: ThemeIcon;
description?: string | IMarkdownString;
status?: ChatSessionStatus;
tooltip?: string | IMarkdownString;
Expand Down
Loading