From 932e9fe9c61bb7d59b4289907aeef0ba97e7dcdb Mon Sep 17 00:00:00 2001 From: Andrew Pareles Date: Fri, 8 Nov 2024 02:50:52 -0800 Subject: [PATCH] progress --- .../contrib/void/browser/registerMetrics.ts | 6 ++ .../contrib/void/browser/registerSettings.ts | 8 +- .../contrib/void/browser/registerSidebar.ts | 88 +++++++++++------ .../void/browser/registerThreadsHistory.ts | 15 ++- .../browser/sidebar/.vscode/extensions.json | 8 -- .../void/browser/sidebar/.vscode/launch.json | 22 ----- .../browser/sidebar/.vscode/settings.json | 18 ---- .../void/browser/sidebar/.vscode/tasks.json | 20 ---- .../contrib/void/browser/sidebar/Sidebar.tsx | 96 +++++++++---------- .../void/browser/sidebar/SidebarChat.tsx | 46 ++++----- .../browser/sidebar/SidebarWebviewProvider.ts | 46 ++++----- .../browser/{util => sidebar}/shared_types.ts | 0 .../{util => sidebar}/systemPrompts.ts | 0 .../contrib/void/browser/util/posthog.ts | 19 ---- 14 files changed, 179 insertions(+), 213 deletions(-) delete mode 100644 src/vs/workbench/contrib/void/browser/sidebar/.vscode/extensions.json delete mode 100644 src/vs/workbench/contrib/void/browser/sidebar/.vscode/launch.json delete mode 100644 src/vs/workbench/contrib/void/browser/sidebar/.vscode/settings.json delete mode 100644 src/vs/workbench/contrib/void/browser/sidebar/.vscode/tasks.json rename src/vs/workbench/contrib/void/browser/{util => sidebar}/shared_types.ts (100%) rename src/vs/workbench/contrib/void/browser/{util => sidebar}/systemPrompts.ts (100%) delete mode 100644 src/vs/workbench/contrib/void/browser/util/posthog.ts diff --git a/src/vs/workbench/contrib/void/browser/registerMetrics.ts b/src/vs/workbench/contrib/void/browser/registerMetrics.ts index 4c256d30..45aa91f2 100644 --- a/src/vs/workbench/contrib/void/browser/registerMetrics.ts +++ b/src/vs/workbench/contrib/void/browser/registerMetrics.ts @@ -30,6 +30,12 @@ class MetricsService extends Disposable implements IMetricsService { console.debug('deviceId', deviceId) posthog.identify(deviceId) + + + // export const captureEvent = (eventId: string, properties: object) => { + // posthog.capture(eventId, properties) + // } + } } diff --git a/src/vs/workbench/contrib/void/browser/registerSettings.ts b/src/vs/workbench/contrib/void/browser/registerSettings.ts index 0297c035..0862197c 100644 --- a/src/vs/workbench/contrib/void/browser/registerSettings.ts +++ b/src/vs/workbench/contrib/void/browser/registerSettings.ts @@ -205,8 +205,14 @@ export type VoidConfig = { const VOID_CONFIG_KEY = 'void.partialVoidConfig' +type setFieldType = (field: K, param: keyof VoidConfigInfo[K], newVal: string) => Promise; + export interface IVoidSettingsService { readonly _serviceBrand: undefined; + onDidChange: Event; + getPartialVoidConfig(): Promise; + getVoidConfig(): Promise; + setField: setFieldType; } export const IVoidSettingsService = createDecorator('voidSettingsService'); @@ -248,7 +254,7 @@ class VoidSettingsService extends Disposable implements IVoidSettingsService { // Set field on PartialVoidConfig - async setField(field: K, param: keyof VoidConfigInfo[K], newVal: string) { + setField: setFieldType = async (field: K, param: keyof VoidConfigInfo[K], newVal: string) => { const partialVoidConfig = await this.getPartialVoidConfig() const newPartialConfig: PartialVoidConfig = { diff --git a/src/vs/workbench/contrib/void/browser/registerSidebar.ts b/src/vs/workbench/contrib/void/browser/registerSidebar.ts index 27a5d1b0..01ac8b52 100644 --- a/src/vs/workbench/contrib/void/browser/registerSidebar.ts +++ b/src/vs/workbench/contrib/void/browser/registerSidebar.ts @@ -37,6 +37,8 @@ import { IOpenerService } from '../../../../platform/opener/common/opener.js'; import { ITelemetryService } from '../../../../platform/telemetry/common/telemetry.js'; import { IHoverService } from '../../../../platform/hover/browser/hover.js'; import { IVoidSettingsService } from './registerSettings.js'; +import { IEditorService } from '../../../services/editor/common/editorService.js'; + // compare against search.contribution.ts and https://app.greptile.com/chat/w1nsmt3lauwzculipycpn?repo=github%3Amain%3Amicrosoft%2Fvscode @@ -78,20 +80,40 @@ class VoidSidebarViewPane extends ViewPane { protected override renderBody(parent: HTMLElement): void { super.renderBody(parent); - const { root, history, chat, settings } = dom.h('div@root', [ - dom.h('div@history', []), + //
+ + const { root, chat, history, settings } = dom.h('div@root', [ dom.h('div@chat', []), + dom.h('div@history', []), dom.h('div@settings', []), ]) root.style.display = 'flex'; root.style.flexDirection = 'column'; root.style.height = '100vh'; root.style.width = '100%'; - - dom.append(parent, root); + this._renderChat(chat); this._renderHistory(history); + this._renderSettings(settings); + } + + + private _renderChat(element: HTMLElement) { + //
+ // + //
+ + + + this._voidSidebarStateService.onDidChange(() => { + }) + + + this._voidSidebarStateService.onFocusChat(() => { + }) + this._voidSidebarStateService.onBlurChat(() => { + }) } @@ -116,12 +138,6 @@ class VoidSidebarViewPane extends ViewPane { } - private _renderChat(element: HTMLElement) { - //
- // - //
- - } } @@ -209,7 +225,7 @@ class VoidSidebarStateService extends Disposable implements IVoidSidebarStateSer @IViewsService private readonly _viewsService: IViewsService, ) { super() - // auto open the view on mount (can view this as initializing state...) + // auto open the view on mount (if it bothers you this is here, this is technically just initializing the state of the view) this._viewsService.openView(SIDEBAR_VIEW_ID); } @@ -247,27 +263,26 @@ registerAction2(class extends Action2 { const stateService = accessor.get(IVoidSidebarStateService) stateService.setState({ isHistoryOpen: false, currentTab: 'chat' }) stateService.focusChat() + + const selection = accessor.get(IEditorService).activeTextEditorControl?.getSelection() + + + // chat state: + // // if user pressed ctrl+l, add their selection to the sidebar + // useOnVSCodeMessage('ctrl+l', (m) => { + // setSelection(m.selection) + // const filepath = m.selection.filePath + + // // add current file to the context if it's not already in the files array + // if (!files.find(f => f.fsPath === filepath.fsPath)) + // setFiles(files => [...files, filepath]) + // }) + + } }); -// History menu button -registerAction2(class extends Action2 { - constructor() { - super({ - id: 'void.historyAction', - title: 'View past chats', - icon: { id: 'history' }, - menu: [{ id: MenuId.ViewTitle, group: 'navigation', when: ContextKeyExpr.equals('view', SIDEBAR_VIEW_ID), }] - }); - } - async run(accessor: ServicesAccessor): Promise { - const stateService = accessor.get(IVoidSidebarStateService) - stateService.setState({ isHistoryOpen: !stateService.state.isHistoryOpen }) - stateService.blurChat() - } -}) - // New chat menu button registerAction2(class extends Action2 { constructor() { @@ -288,6 +303,23 @@ registerAction2(class extends Action2 { } }) +// History menu button +registerAction2(class extends Action2 { + constructor() { + super({ + id: 'void.historyAction', + title: 'View past chats', + icon: { id: 'history' }, + menu: [{ id: MenuId.ViewTitle, group: 'navigation', when: ContextKeyExpr.equals('view', SIDEBAR_VIEW_ID), }] + }); + } + async run(accessor: ServicesAccessor): Promise { + const stateService = accessor.get(IVoidSidebarStateService) + stateService.setState({ isHistoryOpen: !stateService.state.isHistoryOpen }) + stateService.blurChat() + } +}) + // Settings (API config) menu button registerAction2(class extends Action2 { constructor() { diff --git a/src/vs/workbench/contrib/void/browser/registerThreadsHistory.ts b/src/vs/workbench/contrib/void/browser/registerThreadsHistory.ts index 71862436..89fff739 100644 --- a/src/vs/workbench/contrib/void/browser/registerThreadsHistory.ts +++ b/src/vs/workbench/contrib/void/browser/registerThreadsHistory.ts @@ -39,7 +39,7 @@ type ChatMessage = // a "thread" means a chat message history -const createNewThread = () => { +const newThreadObject = () => { const now = new Date().toISOString() return { id: new Date().getTime().toString(), @@ -91,8 +91,17 @@ class ThreadHistoryService extends Disposable implements IThreadHistoryService { startNewThread() { - const newThread = createNewThread() + + // if a thread with 0 messages already exists, switch to it const currentThreads = this.getAllThreads() + for (let threadId in currentThreads) { + if (currentThreads[threadId].messages.length === 0) { + this.switchToThread(threadId) + return + } + } + + const newThread = newThreadObject() this._storeAllThreads({ ...currentThreads, [newThread.id]: newThread @@ -110,7 +119,7 @@ class ThreadHistoryService extends Disposable implements IThreadHistoryService { currentThread = allThreads[this._currentThreadId] } else { - currentThread = createNewThread() + currentThread = newThreadObject() this._currentThreadId = currentThread.id } diff --git a/src/vs/workbench/contrib/void/browser/sidebar/.vscode/extensions.json b/src/vs/workbench/contrib/void/browser/sidebar/.vscode/extensions.json deleted file mode 100644 index 186459d5..00000000 --- a/src/vs/workbench/contrib/void/browser/sidebar/.vscode/extensions.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - // See http://go.microsoft.com/fwlink/?LinkId=827846 - // for the documentation about the extensions.json format - "recommendations": [ - "dbaeumer.vscode-eslint", - "ms-vscode.extension-test-runner" - ] -} diff --git a/src/vs/workbench/contrib/void/browser/sidebar/.vscode/launch.json b/src/vs/workbench/contrib/void/browser/sidebar/.vscode/launch.json deleted file mode 100644 index 17ab1d57..00000000 --- a/src/vs/workbench/contrib/void/browser/sidebar/.vscode/launch.json +++ /dev/null @@ -1,22 +0,0 @@ -// A launch configuration that compiles the extension and then opens it inside a new window -// Use IntelliSense to learn about possible attributes. -// Hover to view descriptions of existing attributes. -// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 -{ - "version": "0.2.0", - "configurations": [ - { - "name": "Run Extension", - "type": "extensionHost", - "request": "launch", - "args": [ - "--extensionDevelopmentPath=${workspaceFolder}", - "--enable-proposed-api=void.void", - ], - "outFiles": [ - "${workspaceFolder}/out/**/*.js" - ], - "preLaunchTask": "${defaultBuildTask}" - } - ] -} \ No newline at end of file diff --git a/src/vs/workbench/contrib/void/browser/sidebar/.vscode/settings.json b/src/vs/workbench/contrib/void/browser/sidebar/.vscode/settings.json deleted file mode 100644 index 3100dfe2..00000000 --- a/src/vs/workbench/contrib/void/browser/sidebar/.vscode/settings.json +++ /dev/null @@ -1,18 +0,0 @@ -// Place your settings in this file to overwrite default and user settings. -{ - "files.exclude": { - "**/.git": true, - "**/.svn": true, - "**/.hg": true, - "**/CVS": true, - "**/.DS_Store": true, - "**/Thumbs.db": true, - "out": false, - "**/node_modules": true - }, - "search.exclude": { - "out": true // set this to false to include "out" folder in search results - }, - // Turn off tsc task auto detection since we have the necessary tasks as npm scripts - "typescript.tsc.autoDetect": "off", -} diff --git a/src/vs/workbench/contrib/void/browser/sidebar/.vscode/tasks.json b/src/vs/workbench/contrib/void/browser/sidebar/.vscode/tasks.json deleted file mode 100644 index 3b17e53b..00000000 --- a/src/vs/workbench/contrib/void/browser/sidebar/.vscode/tasks.json +++ /dev/null @@ -1,20 +0,0 @@ -// See https://go.microsoft.com/fwlink/?LinkId=733558 -// for the documentation about the tasks.json format -{ - "version": "2.0.0", - "tasks": [ - { - "type": "npm", - "script": "watch", - "problemMatcher": "$tsc-watch", - "isBackground": true, - "presentation": { - "reveal": "never" - }, - "group": { - "kind": "build", - "isDefault": true - } - } - ] -} diff --git a/src/vs/workbench/contrib/void/browser/sidebar/Sidebar.tsx b/src/vs/workbench/contrib/void/browser/sidebar/Sidebar.tsx index b3bf8ae3..23674faf 100644 --- a/src/vs/workbench/contrib/void/browser/sidebar/Sidebar.tsx +++ b/src/vs/workbench/contrib/void/browser/sidebar/Sidebar.tsx @@ -1,63 +1,63 @@ -import React, { useState, useRef } from '../void-imports/react.js' -import { SidebarThreadSelector } from './SidebarThreadSelector.js'; -import { SidebarChat } from './SidebarChat.js'; -import { SidebarSettings } from './SidebarSettings.js'; +// import React, { useState, useRef } from '../void-imports/react.js' +// import { SidebarThreadSelector } from './SidebarThreadSelector.js'; +// import { SidebarChat } from './SidebarChat.js'; +// import { SidebarSettings } from './SidebarSettings.js'; -const Sidebar = () => { +// const Sidebar = () => { - const chatInputRef = useRef(null) +// const chatInputRef = useRef(null) - const [tab, setTab] = useState<'threadSelector' | 'chat' | 'settings'>('chat') +// const [tab, setTab] = useState<'threadSelector' | 'chat' | 'settings'>('chat') - // // if they pressed the + to add a new chat - // useOnVSCodeMessage('startNewThread', (m) => { - // setTab('chat'); - // chatInputRef.current?.focus(); - // }) +// // // if they pressed the + to add a new chat +// // useOnVSCodeMessage('startNewThread', (m) => { +// // setTab('chat'); +// // chatInputRef.current?.focus(); +// // }) - // // ctrl+l should switch back to chat - // useOnVSCodeMessage('ctrl+l', (m) => { - // setTab('chat'); - // chatInputRef.current?.focus(); - // }) +// // // ctrl+l should switch back to chat +// // useOnVSCodeMessage('ctrl+l', (m) => { +// // setTab('chat'); +// // chatInputRef.current?.focus(); +// // }) - // // if they toggled thread selector - // useOnVSCodeMessage('toggleThreadSelector', (m) => { - // if (tab === 'threadSelector') { - // setTab('chat') - // chatInputRef.current?.blur(); - // } else - // setTab('threadSelector') - // }) +// // // if they toggled thread selector +// // useOnVSCodeMessage('toggleThreadSelector', (m) => { +// // if (tab === 'threadSelector') { +// // setTab('chat') +// // chatInputRef.current?.blur(); +// // } else +// // setTab('threadSelector') +// // }) - // // if they toggled settings - // useOnVSCodeMessage('toggleSettings', (m) => { - // if (tab === 'settings') { - // setTab('chat') - // chatInputRef.current?.blur(); - // } else - // setTab('settings') - // }) +// // // if they toggled settings +// // useOnVSCodeMessage('toggleSettings', (m) => { +// // if (tab === 'settings') { +// // setTab('chat') +// // chatInputRef.current?.blur(); +// // } else +// // setTab('settings') +// // }) - return <> -
+// return <> +//
-
- setTab('chat')} /> -
+//
+// setTab('chat')} /> +//
-
- -
+//
+// +//
-
- -
+//
+// +//
-
- +//
+// -} +// } -export default Sidebar +// export default Sidebar diff --git a/src/vs/workbench/contrib/void/browser/sidebar/SidebarChat.tsx b/src/vs/workbench/contrib/void/browser/sidebar/SidebarChat.tsx index 746b51e6..2b58705a 100644 --- a/src/vs/workbench/contrib/void/browser/sidebar/SidebarChat.tsx +++ b/src/vs/workbench/contrib/void/browser/sidebar/SidebarChat.tsx @@ -147,6 +147,29 @@ const ChatBubble = ({ chatMessage }: { chatMessage: ChatMessage }) => { export const SidebarChat = ({ chatInputRef }: { chatInputRef: React.RefObject }) => { + // // if they pressed the + to add a new chat + // useOnVSCodeMessage('startNewThread', (m) => { + // const allThreads = getAllThreads() + // // find a thread with 0 messages and switch to it + // for (let threadId in allThreads) { + // if (allThreads[threadId].messages.length === 0) { + // switchToThread(threadId) + // return + // } + // } + // // start a new thread + // startNewThread() + // }) + + // // if user pressed ctrl+l, add their selection to the sidebar + // useOnVSCodeMessage('ctrl+l', (m) => { + // setSelection(m.selection) + // const filepath = m.selection.filePath + + // // add current file to the context if it's not already in the files array + // if (!files.find(f => f.fsPath === filepath.fsPath)) + // setFiles(files => [...files, filepath]) + // }) // state of current message const [selection, setSelection] = useState(null) // the code the user is selecting @@ -167,29 +190,6 @@ export const SidebarChat = ({ chatInputRef }: { chatInputRef: React.RefObject { - const allThreads = getAllThreads() - // find a thread with 0 messages and switch to it - for (let threadId in allThreads) { - if (allThreads[threadId].messages.length === 0) { - switchToThread(threadId) - return - } - } - // start a new thread - startNewThread() - }) - - // if user pressed ctrl+l, add their selection to the sidebar - useOnVSCodeMessage('ctrl+l', (m) => { - setSelection(m.selection) - const filepath = m.selection.filePath - - // add current file to the context if it's not already in the files array - if (!files.find(f => f.fsPath === filepath.fsPath)) - setFiles(files => [...files, filepath]) - }) const isDisabled = !instructions diff --git a/src/vs/workbench/contrib/void/browser/sidebar/SidebarWebviewProvider.ts b/src/vs/workbench/contrib/void/browser/sidebar/SidebarWebviewProvider.ts index 08191944..6cdc842e 100644 --- a/src/vs/workbench/contrib/void/browser/sidebar/SidebarWebviewProvider.ts +++ b/src/vs/workbench/contrib/void/browser/sidebar/SidebarWebviewProvider.ts @@ -1,30 +1,30 @@ -// renders the code from `src/sidebar` +// // renders the code from `src/sidebar` -import * as vscode from 'vscode'; -import { updateWebviewHTML as _updateWebviewHTML } from './src/extension/extensionLib/updateWebviewHTML'; +// import * as vscode from 'vscode'; +// import { updateWebviewHTML as _updateWebviewHTML } from './src/extension/extensionLib/updateWebviewHTML'; -export class SidebarWebviewProvider implements vscode.WebviewViewProvider { - public static readonly viewId = 'void.viewnumberone'; +// export class SidebarWebviewProvider implements vscode.WebviewViewProvider { +// public static readonly viewId = 'void.viewnumberone'; - public webview: Promise // used to send messages to the webview, resolved by _res in resolveWebviewView - private _res: (c: vscode.Webview) => void // used to resolve the webview +// public webview: Promise // used to send messages to the webview, resolved by _res in resolveWebviewView +// private _res: (c: vscode.Webview) => void // used to resolve the webview - private readonly _extensionUri: vscode.Uri +// private readonly _extensionUri: vscode.Uri - constructor(context: vscode.ExtensionContext) { - // const extensionPath = context.extensionPath // the directory where the extension is installed, might be useful later... was included in webviewProvider code - this._extensionUri = context.extensionUri +// constructor(context: vscode.ExtensionContext) { +// // const extensionPath = context.extensionPath // the directory where the extension is installed, might be useful later... was included in webviewProvider code +// this._extensionUri = context.extensionUri - let temp_res: typeof this._res | undefined = undefined - this.webview = new Promise((res, rej) => { temp_res = res }) - if (!temp_res) throw new Error("Void sidebar provider: resolver was undefined") - this._res = temp_res - } +// let temp_res: typeof this._res | undefined = undefined +// this.webview = new Promise((res, rej) => { temp_res = res }) +// if (!temp_res) throw new Error("Void sidebar provider: resolver was undefined") +// this._res = temp_res +// } - // called internally by vscode - resolveWebviewView(webviewView: vscode.WebviewView, context: vscode.WebviewViewResolveContext, token: vscode.CancellationToken,) { - const webview = webviewView.webview; - _updateWebviewHTML(webview, this._extensionUri, { jsOutLocation: 'dist/webviews/sidebar/index.js', cssOutLocation: 'dist/webviews/styles.css' }) - this._res(webview); // resolve webview and _webviewView - } -} +// // called internally by vscode +// resolveWebviewView(webviewView: vscode.WebviewView, context: vscode.WebviewViewResolveContext, token: vscode.CancellationToken,) { +// const webview = webviewView.webview; +// _updateWebviewHTML(webview, this._extensionUri, { jsOutLocation: 'dist/webviews/sidebar/index.js', cssOutLocation: 'dist/webviews/styles.css' }) +// this._res(webview); // resolve webview and _webviewView +// } +// } diff --git a/src/vs/workbench/contrib/void/browser/util/shared_types.ts b/src/vs/workbench/contrib/void/browser/sidebar/shared_types.ts similarity index 100% rename from src/vs/workbench/contrib/void/browser/util/shared_types.ts rename to src/vs/workbench/contrib/void/browser/sidebar/shared_types.ts diff --git a/src/vs/workbench/contrib/void/browser/util/systemPrompts.ts b/src/vs/workbench/contrib/void/browser/sidebar/systemPrompts.ts similarity index 100% rename from src/vs/workbench/contrib/void/browser/util/systemPrompts.ts rename to src/vs/workbench/contrib/void/browser/sidebar/systemPrompts.ts diff --git a/src/vs/workbench/contrib/void/browser/util/posthog.ts b/src/vs/workbench/contrib/void/browser/util/posthog.ts deleted file mode 100644 index cccf2010..00000000 --- a/src/vs/workbench/contrib/void/browser/util/posthog.ts +++ /dev/null @@ -1,19 +0,0 @@ -import posthog from '../void-imports/posthog-js.js' - -export const identifyUser = (id: string) => { - posthog.identify(id) -} - -export const captureEvent = (eventId: string, properties: object) => { - posthog.capture(eventId, properties) -} - -export const initPosthog = () => { - // We send absolutely no code to the server. We only track usage metrics like button clicks, etc. This might change and we might eventually add an opt-in or opt-out. - posthog.init('phc_UanIdujHiLp55BkUTjB1AuBXcasVkdqRwgnwRlWESH2', - { - api_host: 'https://us.i.posthog.com', - person_profiles: 'identified_only' // we only track events from identified users. We identify them in Sidebar - } - ) -}