mirror of
https://github.com/voideditor/void
synced 2026-05-24 09:58:23 +00:00
history ux
This commit is contained in:
parent
c921059690
commit
b7db527866
6 changed files with 62 additions and 23 deletions
|
|
@ -295,12 +295,13 @@ const PastThreadElement = ({ pastThread, idx, hoveredIdx, setHoveredIdx }: { pas
|
|||
|
||||
const numMessages = pastThread.messages.filter((msg) => msg.role === 'assistant' || msg.role === 'user').length;
|
||||
|
||||
const dateHTML = <span
|
||||
className='inline-flex items-center'
|
||||
data-tooltip-id='void-tooltip'
|
||||
data-tooltip-content={`Last modified ${formatTime(new Date(pastThread.lastModified))}`}
|
||||
data-tooltip-place='top'
|
||||
const optionsHTML = <span
|
||||
className='gap-1 inline-flex items-center'
|
||||
// data-tooltip-id='void-tooltip'
|
||||
// data-tooltip-content={`Last modified ${formatTime(new Date(pastThread.lastModified))}`}
|
||||
// data-tooltip-place='top'
|
||||
>
|
||||
{/* <span>{numMessages}</span> */}
|
||||
{formatDate(new Date(pastThread.lastModified))}
|
||||
</span>
|
||||
|
||||
|
|
@ -315,10 +316,6 @@ const PastThreadElement = ({ pastThread, idx, hoveredIdx, setHoveredIdx }: { pas
|
|||
}}
|
||||
onMouseEnter={() => setHoveredIdx(idx)}
|
||||
onMouseLeave={() => setHoveredIdx(null)}
|
||||
data-tooltip-id='void-tooltip'
|
||||
data-tooltip-content={`${numMessages} messages`}
|
||||
data-tooltip-place='top'
|
||||
data-tooltip-delay-show={500}
|
||||
>
|
||||
<div className="flex items-center justify-between gap-1">
|
||||
<span className="flex items-center gap-2 min-w-0 overflow-hidden">
|
||||
|
|
@ -328,7 +325,7 @@ const PastThreadElement = ({ pastThread, idx, hoveredIdx, setHoveredIdx }: { pas
|
|||
<div className="flex items-center gap-2 opacity-60">
|
||||
{idx === hoveredIdx ?
|
||||
<TrashButton threadId={pastThread.id} />
|
||||
: dateHTML
|
||||
: optionsHTML
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
--void-bg-1-alt: var(--vscode-badge-background);
|
||||
--void-bg-2: var(--vscode-sideBar-background);
|
||||
--void-bg-2-alt: color-mix(in srgb, var(--vscode-editor-background) 30%, var(--vscode-sideBar-background) 70%);
|
||||
--void-bg-2-hover: color-mix(in srgb, var(--vscode-editor-foreground) 5%, var(--vscode-sideBar-background) 95%);
|
||||
--void-bg-2-hover: color-mix(in srgb, var(--vscode-editor-foreground) 2%, var(--vscode-sideBar-background) 98%);
|
||||
--void-bg-3: var(--vscode-editor-background);
|
||||
|
||||
--void-fg-0: color-mix(in srgb, var(--vscode-tab-activeForeground) 90%, black 10%);
|
||||
|
|
|
|||
|
|
@ -689,7 +689,7 @@ export const VoidCustomDropdownBox = <T extends NonNullable<any>>({
|
|||
key={optionName}
|
||||
className={`flex items-center px-2 py-1 pr-4 cursor-pointer whitespace-nowrap
|
||||
transition-all duration-100
|
||||
${thisOptionIsSelected ? 'bg-void-bg-2-hover' : 'bg-void-bg-2 hover:bg-void-bg-2-hover'}
|
||||
${thisOptionIsSelected ? 'bg-void-bg-2-hover' : 'bg-void-bg-2-alt hover:bg-void-bg-2-hover'}
|
||||
`}
|
||||
onClick={() => {
|
||||
onChangeOption(option);
|
||||
|
|
|
|||
|
|
@ -686,7 +686,7 @@ const transferTheseFilesOfOS = (os: 'mac' | 'windows' | 'linux' | null, fromEdit
|
|||
}, {
|
||||
from: URI.joinPath(URI.from({ scheme: 'file' }), userprofile, '.cursor', 'extensions'),
|
||||
to: URI.joinPath(URI.from({ scheme: 'file' }), userprofile, '.void-editor', 'extensions'),
|
||||
}]
|
||||
}]
|
||||
} else if (fromEditor === 'Windsurf') {
|
||||
return [{
|
||||
from: URI.joinPath(URI.from({ scheme: 'file' }), appdata, 'Windsurf', 'User', 'settings.json'),
|
||||
|
|
|
|||
|
|
@ -202,7 +202,19 @@ registerAction2(class extends Action2 {
|
|||
})
|
||||
|
||||
|
||||
const openNewThreadAndFireFocus = (accessor: ServicesAccessor) => {
|
||||
|
||||
const stateService = accessor.get(ISidebarStateService)
|
||||
stateService.setState({ isHistoryOpen: false, currentTab: 'chat' })
|
||||
const chatThreadService = accessor.get(IChatThreadService)
|
||||
chatThreadService.openNewThread()
|
||||
|
||||
// focus
|
||||
stateService.fireFocusChat()
|
||||
const window = getActiveWindow()
|
||||
window.requestAnimationFrame(() => stateService.fireFocusChat())
|
||||
|
||||
}
|
||||
|
||||
|
||||
// New chat menu button
|
||||
|
|
@ -213,6 +225,25 @@ registerAction2(class extends Action2 {
|
|||
title: 'New Chat',
|
||||
icon: { id: 'add' },
|
||||
menu: [{ id: MenuId.ViewTitle, group: 'navigation', when: ContextKeyExpr.equals('view', VOID_VIEW_ID), }],
|
||||
|
||||
});
|
||||
}
|
||||
async run(accessor: ServicesAccessor): Promise<void> {
|
||||
|
||||
const metricsService = accessor.get(IMetricsService)
|
||||
metricsService.capture('Chat Navigation', { type: 'New Chat' })
|
||||
|
||||
openNewThreadAndFireFocus(accessor)
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
// New chat keybind
|
||||
registerAction2(class extends Action2 {
|
||||
constructor() {
|
||||
super({
|
||||
id: 'void.newChatKeybindAction',
|
||||
title: 'New Chat Keybind',
|
||||
keybinding: {
|
||||
primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KeyL,
|
||||
weight: KeybindingWeight.VoidExtension,
|
||||
|
|
@ -220,19 +251,16 @@ registerAction2(class extends Action2 {
|
|||
});
|
||||
}
|
||||
async run(accessor: ServicesAccessor): Promise<void> {
|
||||
const stateService = accessor.get(ISidebarStateService)
|
||||
|
||||
const metricsService = accessor.get(IMetricsService)
|
||||
const commandService = accessor.get(ICommandService)
|
||||
metricsService.capture('Chat Navigation', { type: 'New Chat Keybind' })
|
||||
|
||||
metricsService.capture('Chat Navigation', { type: 'New Chat' })
|
||||
openNewThreadAndFireFocus(accessor)
|
||||
|
||||
stateService.setState({ isHistoryOpen: false, currentTab: 'chat' })
|
||||
const chatThreadService = accessor.get(IChatThreadService)
|
||||
chatThreadService.openNewThread()
|
||||
// add user's selection to chat
|
||||
await commandService.executeCommand(VOID_CTRL_L_ACTION_ID)
|
||||
|
||||
// focus
|
||||
stateService.fireFocusChat()
|
||||
const window = getActiveWindow()
|
||||
window.requestAnimationFrame(() => stateService.fireFocusChat())
|
||||
}
|
||||
})
|
||||
|
||||
|
|
@ -247,13 +275,27 @@ registerAction2(class extends Action2 {
|
|||
});
|
||||
}
|
||||
async run(accessor: ServicesAccessor): Promise<void> {
|
||||
|
||||
// do not do anything if there are no messages (without this it clears all of the user's selections if the button is pressed)
|
||||
// TODO the history button should be disabled in this case so we can remove this logic
|
||||
const thread = accessor.get(IChatThreadService).getCurrentThread()
|
||||
if (thread.messages.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const stateService = accessor.get(ISidebarStateService)
|
||||
const metricsService = accessor.get(IMetricsService)
|
||||
|
||||
|
||||
metricsService.capture('Chat Navigation', { type: 'History' })
|
||||
|
||||
openNewThreadAndFireFocus(accessor)
|
||||
|
||||
// doesnt do anything right now
|
||||
stateService.setState({ isHistoryOpen: !stateService.state.isHistoryOpen, currentTab: 'chat' })
|
||||
stateService.fireBlurChat()
|
||||
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import { VOID_OPEN_SIDEBAR_ACTION_ID } from './sidebarPane.js';
|
|||
|
||||
// service that manages sidebar's state
|
||||
export type VoidSidebarState = {
|
||||
isHistoryOpen: boolean;
|
||||
isHistoryOpen: boolean; // this isn't doing anything right now
|
||||
currentTab: 'chat';
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue