1
1
import { cloneDeep } from 'lodash' ;
2
2
import vscode , { Uri } from 'vscode' ;
3
3
import path from 'path' ;
4
- import fs from 'fs' ;
5
4
import { Post } from '../models/post' ;
6
5
import { globalState } from './global-state' ;
7
6
import { postCategoryService } from './post-category.service' ;
@@ -13,6 +12,7 @@ import { webviewMessage } from '../models/webview-message';
13
12
import { webviewCommand } from '../models/webview-command' ;
14
13
import { uploadImage } from '../commands/upload-image/upload-image' ;
15
14
import { ImageUploadStatusId } from '../models/image-upload-status' ;
15
+ import { openPostFile } from '../commands/posts-list/open-post-file' ;
16
16
17
17
const panels : Map < string , vscode . WebviewPanel > = new Map ( ) ;
18
18
@@ -23,6 +23,8 @@ export namespace postConfigurationPanel {
23
23
panelTitle ?: string ;
24
24
localFileUri ?: Uri ;
25
25
breadcrumbs ?: string [ ] ;
26
+ successCallback : ( post : Post ) => any ;
27
+ beforeUpdate ?: ( postToUpdate : Post , panel : vscode . WebviewPanel ) => Promise < boolean > ;
26
28
}
27
29
const resourceRootUri = ( ) =>
28
30
vscode . Uri . file ( path . join ( globalState . extensionContext ! . extensionPath , 'dist' , 'assets' ) ) ;
@@ -37,29 +39,19 @@ export namespace postConfigurationPanel {
37
39
} ;
38
40
39
41
export const buildPanelId = ( postId : number , postTitle : string ) : string => `${ postId } -${ postTitle } ` ;
40
- export const findPanel = ( panelId : string ) => panels . get ( panelId ) ;
41
-
42
- export const open = async (
43
- option : PostConfigurationPanelOpenOption ,
44
- successCallback : ( post : Post ) => any ,
45
- beforeUpdate ?: ( postToUpdate : Post , panel : vscode . WebviewPanel ) => Promise < boolean >
46
- ) => {
47
- let { post, panelTitle, localFileUri, breadcrumbs } = option ;
48
- const { extensionContext } = globalState ;
49
- if ( ! panelTitle ) {
50
- panelTitle = `博文设置 - ${ post . title } ` ;
51
- }
52
- if ( localFileUri && fs . existsSync ( localFileUri . fsPath ) ) {
53
- await vscode . commands . executeCommand ( 'vscode.open' , localFileUri , {
54
- preview : false ,
55
- viewColumn : vscode . ViewColumn . One ,
56
- } as vscode . TextDocumentShowOptions ) ;
57
- }
42
+ export const findPanelById = ( panelId : string ) => panels . get ( panelId ) ;
43
+ export const open = async ( option : PostConfigurationPanelOpenOption ) => {
44
+ let { post, panelTitle, breadcrumbs } = option ;
45
+ panelTitle = panelTitle ? panelTitle : `博文设置 - ${ post . title } ` ;
46
+ await openPostFile ( post , {
47
+ viewColumn : vscode . ViewColumn . One ,
48
+ } ) ;
58
49
const panelId = buildPanelId ( post . id , post . title ) ;
59
- let panel = findPanel ( panelId ) ;
60
- if ( revealPanel ( panel , option ) ) {
50
+ let panel = tryRevealPanel ( panelId , option ) ;
51
+ if ( panel ) {
61
52
return ;
62
53
}
54
+ let disposables : ( vscode . Disposable | undefined ) [ ] = [ ] ;
63
55
panel = await createPanel ( panelTitle , post ) ;
64
56
const { webview } = panel ;
65
57
await webview . postMessage ( {
@@ -75,63 +67,23 @@ export namespace postConfigurationPanel {
75
67
tags : cloneDeep ( await postTagService . fetchTags ( ) ) ,
76
68
breadcrumbs,
77
69
} as webviewMessage . EditPostConfigurationMessage ) ;
78
- webview . onDidReceiveMessage (
79
- async message => {
80
- const { command } = ( message ?? { } ) as webviewMessage . Message ;
81
- switch ( command ) {
82
- case webviewCommand . ExtensionCommands . savePost :
83
- try {
84
- if ( ! panel ) {
85
- return ;
86
- }
87
- const { post : postToUpdate } = message as webviewMessage . SavePostMessage ;
88
- if ( beforeUpdate ) {
89
- if ( ! ( await beforeUpdate ( postToUpdate , panel ) ) ) {
90
- panel . dispose ( ) ;
91
- return ;
92
- }
93
- }
94
- const postSavedModel = await postService . updatePost ( postToUpdate ) ;
95
- panel . dispose ( ) ;
96
- successCallback ( Object . assign ( { } , postToUpdate , postSavedModel ) ) ;
97
- } catch ( err ) {
98
- if ( isErrorResponse ( err ) ) {
99
- await webview . postMessage ( {
100
- command : webviewCommand . UiCommands . showErrorResponse ,
101
- errorResponse : err ,
102
- } as webviewMessage . ShowErrorResponseMessage ) ;
103
- } else {
104
- throw err ;
105
- }
106
- }
107
- break ;
108
- case webviewCommand . ExtensionCommands . disposePanel :
109
- panel ?. dispose ( ) ;
110
- break ;
111
- case webviewCommand . ExtensionCommands . uploadImage :
112
- await handleUploadImageCommand ( panel , message as any ) ;
113
- break ;
114
- }
115
- } ,
116
- undefined ,
117
- globalState . extensionContext ?. subscriptions
118
- ) ;
119
- panel . onDidDispose (
120
- ( ) => {
121
- panels . delete ( panelId ) ;
122
- panel = undefined ;
123
- } ,
124
- undefined ,
125
- extensionContext ! . subscriptions
70
+ disposables . push (
71
+ observeWebviewMessages ( panel , option ) ,
72
+ observeActiveColorSchemaChange ( panel ) ,
73
+ observerPanelDisposeEvent ( panel , disposables )
126
74
) ;
127
75
} ;
128
76
129
- const revealPanel = (
130
- panel : vscode . WebviewPanel | null | undefined ,
77
+ const tryRevealPanel = (
78
+ panelId : string | undefined ,
131
79
options : PostConfigurationPanelOpenOption
132
- ) : panel is vscode . WebviewPanel => {
80
+ ) : vscode . WebviewPanel | undefined => {
81
+ if ( ! panelId ) {
82
+ return ;
83
+ }
84
+ const panel = findPanelById ( panelId ) ;
133
85
if ( ! panel ) {
134
- return false ;
86
+ return ;
135
87
}
136
88
try {
137
89
const { breadcrumbs } = options ;
@@ -141,10 +93,11 @@ export namespace postConfigurationPanel {
141
93
breadcrumbs,
142
94
} as webviewMessage . UpdateBreadcrumbsMessage ) ;
143
95
panel . reveal ( ) ;
144
- return true ;
145
96
} catch {
146
- return false ;
97
+ return undefined ;
147
98
}
99
+
100
+ return panel ;
148
101
} ;
149
102
150
103
const createPanel = async ( panelTitle : string , post : Post ) : Promise < vscode . WebviewPanel > => {
@@ -160,7 +113,7 @@ export namespace postConfigurationPanel {
160
113
return panel ;
161
114
} ;
162
115
163
- const handleUploadImageCommand = async (
116
+ const onUploadImageCommand = async (
164
117
panel : vscode . WebviewPanel | undefined ,
165
118
message : webviewMessage . UploadImageMessage
166
119
) => {
@@ -197,4 +150,83 @@ export namespace postConfigurationPanel {
197
150
}
198
151
}
199
152
} ;
153
+
154
+ const observeActiveColorSchemaChange = ( panel : vscode . WebviewPanel | undefined ) : vscode . Disposable | undefined => {
155
+ if ( ! panel ) {
156
+ return ;
157
+ }
158
+ const { webview } = panel ;
159
+ return vscode . window . onDidChangeActiveColorTheme ( async theme => {
160
+ await webview . postMessage ( {
161
+ command : webviewCommand . UiCommands . changeTheme ,
162
+ colorThemeKind : theme . kind ,
163
+ } as webviewMessage . ChangeThemeMessage ) ;
164
+ } ) ;
165
+ } ;
166
+
167
+ const observeWebviewMessages = (
168
+ panel : vscode . WebviewPanel | undefined ,
169
+ options : PostConfigurationPanelOpenOption
170
+ ) : vscode . Disposable | undefined => {
171
+ if ( ! panel ) {
172
+ return ;
173
+ }
174
+ const { webview } = panel ;
175
+ const { beforeUpdate, successCallback } = options ;
176
+ return webview . onDidReceiveMessage ( async message => {
177
+ const { command } = ( message ?? { } ) as webviewMessage . Message ;
178
+ switch ( command ) {
179
+ case webviewCommand . ExtensionCommands . savePost :
180
+ try {
181
+ if ( ! panel ) {
182
+ return ;
183
+ }
184
+ const { post : postToUpdate } = message as webviewMessage . SavePostMessage ;
185
+ if ( beforeUpdate ) {
186
+ if ( ! ( await beforeUpdate ( postToUpdate , panel ) ) ) {
187
+ panel . dispose ( ) ;
188
+ return ;
189
+ }
190
+ }
191
+ const postSavedModel = await postService . updatePost ( postToUpdate ) ;
192
+ panel . dispose ( ) ;
193
+ successCallback ( Object . assign ( { } , postToUpdate , postSavedModel ) ) ;
194
+ } catch ( err ) {
195
+ if ( isErrorResponse ( err ) ) {
196
+ await webview . postMessage ( {
197
+ command : webviewCommand . UiCommands . showErrorResponse ,
198
+ errorResponse : err ,
199
+ } as webviewMessage . ShowErrorResponseMessage ) ;
200
+ } else {
201
+ throw err ;
202
+ }
203
+ }
204
+ break ;
205
+ case webviewCommand . ExtensionCommands . disposePanel :
206
+ panel ?. dispose ( ) ;
207
+ break ;
208
+ case webviewCommand . ExtensionCommands . uploadImage :
209
+ await onUploadImageCommand ( panel , message as any ) ;
210
+ break ;
211
+ }
212
+ } ) ;
213
+ } ;
214
+
215
+ const observerPanelDisposeEvent = (
216
+ panel : vscode . WebviewPanel | undefined ,
217
+ disposables : ( vscode . Disposable | undefined ) [ ]
218
+ ) : vscode . Disposable | undefined => {
219
+ if ( ! panel ) {
220
+ return ;
221
+ }
222
+
223
+ return panel . onDidDispose ( ( ) => {
224
+ if ( panel ) {
225
+ const panelId = panel . viewType ;
226
+ panels . delete ( panelId ) ;
227
+ panel = undefined ;
228
+ disposables . forEach ( disposable => disposable ?. dispose ( ) ) ;
229
+ }
230
+ } ) ;
231
+ } ;
200
232
}
0 commit comments