1- import type { Webview , WebviewView , WebviewViewProvider } from 'vscode'
21import { ExtensionMode , Uri } from 'vscode'
3- import { extensionContext as context , executeCommand } from 'reactive-vscode'
2+ import {
3+ computed ,
4+ extensionContext as context ,
5+ createSingletonComposable ,
6+ executeCommand ,
7+ ref ,
8+ useWebviewView ,
9+ } from 'reactive-vscode'
410
511import { DiffTreeView } from './diff/DiffTreeView'
612
@@ -10,103 +16,36 @@ import { CHANNEL, EXTENSION_SYMBOL, WEBVIEW_CHANNEL } from '@/constant'
1016
1117import type { Commit } from '@/git'
1218
13- export class GitPanelViewProvider implements WebviewViewProvider {
14- private git = useGitService ( )
15- private storage = useStorage ( )
16- private gitChangesProvider : DiffTreeView
17- public static readonly viewType = `${ EXTENSION_SYMBOL } .history`
18- private _commits : Commit [ ] = [ ]
19- private _view ?: WebviewView
20-
21- constructor (
22- private readonly _extensionUri : Uri ,
23- ) {
24- this . gitChangesProvider = DiffTreeView . getInstance ( )
25- this . _commits = this . storage . getCommits ( )
26- }
27-
28- public async refreshHistory ( forceRefresh : boolean = false ) {
29- if ( ! this . _view )
30- return
31-
32- try {
33- if ( this . _commits . length === 0 || forceRefresh ) {
34- const history = await this . git . getHistory ( )
35- this . _commits = Array . from ( history . all )
36-
37- this . storage . saveCommits ( this . _commits )
38- }
19+ function getNonce ( ) {
20+ let text = ''
21+ const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
22+ for ( let i = 0 ; i < 32 ; i ++ )
23+ text += possible . charAt ( Math . floor ( Math . random ( ) * possible . length ) )
24+ return text
25+ }
3926
40- this . _view . webview . postMessage ( {
41- command : CHANNEL . HISTORY ,
42- commits : this . _commits ,
43- } )
44- }
45- catch ( error ) {
46- this . _view . webview . postMessage ( {
47- command : 'Failed to get git history' ,
48- message : `${ error } ` ,
49- } )
50- }
51- }
27+ export const useGitPanelView = createSingletonComposable ( ( ) => {
28+ const git = useGitService ( )
29+ const storage = useStorage ( )
5230
53- public resolveWebviewView (
54- webviewView : WebviewView ,
55- ) {
56- this . _view = webviewView
57- webviewView . webview . options = {
58- enableScripts : true ,
59- localResourceRoots : [
60- Uri . joinPath ( this . _extensionUri , '../' ) ,
61- Uri . joinPath ( this . _extensionUri ) ,
62- ] ,
63- }
31+ const extensionUri = context . value ?. extensionUri || Uri . file ( context . value ?. extensionPath || '' )
6432
65- webviewView . webview . html = this . _getHtmlForWebview ( webviewView . webview )
66-
67- // Handle messages from webview
68- webviewView . webview . onDidReceiveMessage ( async ( message ) => {
69- switch ( message . command ) {
70- case WEBVIEW_CHANNEL . GET_HISTORY :
71- await this . refreshHistory ( message . forceRefresh )
72- break
73-
74- case WEBVIEW_CHANNEL . SHOW_COMMIT_DETAILS :
75- try {
76- this . gitChangesProvider . refresh ( message . commitHash )
77- }
78- catch ( error ) {
79- webviewView . webview . postMessage ( {
80- command : 'Failed to show commit details' ,
81- message : `${ error } ` ,
82- } )
83- }
84- break
85- case WEBVIEW_CHANNEL . SHOW_CHANGES_PANEL :
86- await executeCommand ( 'git-panel.changes.focus' )
87- break
88-
89- case 'clearHistory' :
90- this . storage . clearCommits ( )
91- break
92- }
93- } )
33+ if ( ! extensionUri ) {
34+ throw new Error ( 'Extension context not initialized' )
9435 }
9536
96- private _getHtmlForWebview ( webview : Webview ) {
97- const isDev = context . value ?. extensionMode === ExtensionMode . Development
37+ const gitChangesProvider = DiffTreeView . getInstance ( )
38+ const commits = ref < Commit [ ] > ( storage . getCommits ( ) )
9839
40+ const isDev = context . value ?. extensionMode === ExtensionMode . Development
41+ const html = computed ( ( ) => {
9942 const scriptUri = isDev
10043 ? 'http://localhost:5173/src/views/history/index.ts'
101- : webview . asWebviewUri (
102- Uri . joinPath ( this . _extensionUri , 'views.es.js' ) ,
103- )
44+ : Uri . joinPath ( extensionUri , 'views.es.js' )
10445
10546 const styleUri = isDev
10647 ? null
107- : webview . asWebviewUri (
108- Uri . joinPath ( this . _extensionUri , 'views.css' ) ,
109- )
48+ : Uri . joinPath ( extensionUri , 'views.css' )
11049
11150 const nonce = getNonce ( )
11251
@@ -135,13 +74,80 @@ export class GitPanelViewProvider implements WebviewViewProvider {
13574 <script type="module" nonce="${ nonce } " src="${ scriptUri } "></script>
13675 </body>
13776 </html>`
77+ } )
78+
79+ const { forceRefresh : refreshWebview , postMessage } = useWebviewView (
80+ `${ EXTENSION_SYMBOL } .history` ,
81+ html ,
82+ {
83+ retainContextWhenHidden : true ,
84+ webviewOptions : {
85+ enableCommandUris : true ,
86+ enableScripts : true ,
87+ localResourceRoots : [
88+ Uri . joinPath ( extensionUri , '../' ) ,
89+ Uri . joinPath ( extensionUri ) ,
90+ ] ,
91+ } ,
92+ onDidReceiveMessage : async ( message ) => {
93+ switch ( message . command ) {
94+ case WEBVIEW_CHANNEL . GET_HISTORY :
95+ await refreshHistory ( message . forceRefresh )
96+ break
97+
98+ case WEBVIEW_CHANNEL . SHOW_COMMIT_DETAILS :
99+ try {
100+ gitChangesProvider . refresh ( message . commitHash )
101+ }
102+ catch ( error ) {
103+ postMessage ( {
104+ command : 'Failed to show commit details' ,
105+ message : `${ error } ` ,
106+ } )
107+ }
108+ break
109+
110+ case WEBVIEW_CHANNEL . SHOW_CHANGES_PANEL :
111+ await executeCommand ( 'git-panel.changes.focus' )
112+ break
113+
114+ case 'clearHistory' :
115+ storage . clearCommits ( )
116+ break
117+ }
118+ } ,
119+ } ,
120+ )
121+
122+ async function refreshHistory ( forceRefresh : boolean = false ) {
123+ try {
124+ if ( commits . value . length === 0 || forceRefresh ) {
125+ const history = await git . getHistory ( )
126+ commits . value = Array . from ( history . all )
127+ storage . saveCommits ( commits . value )
128+ }
129+
130+ postMessage ( {
131+ command : CHANNEL . HISTORY ,
132+ commits : commits . value ,
133+ } )
134+ }
135+ catch ( error ) {
136+ postMessage ( {
137+ command : 'Failed to get git history' ,
138+ message : `${ error } ` ,
139+ } )
140+ }
138141 }
139- }
140142
141- function getNonce ( ) {
142- let text = ''
143- const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
144- for ( let i = 0 ; i < 32 ; i ++ )
145- text += possible . charAt ( Math . floor ( Math . random ( ) * possible . length ) )
146- return text
147- }
143+ function forceRefresh ( ) {
144+ refreshHistory ( true )
145+ refreshWebview ( )
146+ }
147+
148+ return {
149+ viewType : `${ EXTENSION_SYMBOL } .history` as const ,
150+ refreshHistory,
151+ forceRefresh,
152+ }
153+ } )
0 commit comments