4
4
import { commands , Disposable , ExtensionContext , ViewColumn , WebviewPanel , window } from "vscode" ;
5
5
import { leetCodeExecutor } from "../leetCodeExecutor" ;
6
6
import { IProblem } from "../shared" ;
7
+ import { markdownEngine } from "./markdownEngine" ;
8
+
7
9
class LeetCodePreviewProvider implements Disposable {
8
10
9
11
private context : ExtensionContext ;
@@ -14,22 +16,29 @@ class LeetCodePreviewProvider implements Disposable {
14
16
this . context = context ;
15
17
}
16
18
17
- public async preview ( node : IProblem ) : Promise < void > {
19
+ public async show ( node : IProblem ) : Promise < void > {
20
+ // Fetch problem first before creating webview panel
21
+ const descString : string = await leetCodeExecutor . getDescription ( node ) ;
22
+
18
23
this . node = node ;
19
24
if ( ! this . panel ) {
20
- this . panel = window . createWebviewPanel ( "leetcode.preview" , "Preview Problem" , ViewColumn . Active , {
25
+ this . panel = window . createWebviewPanel ( "leetcode.preview" , "Preview Problem" , ViewColumn . One , {
21
26
enableScripts : true ,
22
27
enableCommandUris : true ,
23
28
enableFindWidget : true ,
24
29
retainContextWhenHidden : true ,
30
+ localResourceRoots : markdownEngine . localResourceRoots ,
25
31
} ) ;
26
32
27
33
this . panel . webview . onDidReceiveMessage ( async ( message : IWebViewMessage ) => {
28
34
switch ( message . command ) {
29
- case "ShowProblem" :
35
+ case "ShowProblem" : {
30
36
await commands . executeCommand ( "leetcode.showProblem" , this . node ) ;
31
- this . dispose ( ) ;
32
- return ;
37
+ await commands . executeCommand ( "workbench.action.focusSecondEditorGroup" ) ;
38
+ commands . executeCommand ( "workbench.action.toggleSidebarVisibility" ) ;
39
+ this . panel ! . reveal ( ViewColumn . Two , true ) ;
40
+ break ;
41
+ }
33
42
}
34
43
} , this , this . context . subscriptions ) ;
35
44
@@ -38,9 +47,10 @@ class LeetCodePreviewProvider implements Disposable {
38
47
} , null , this . context . subscriptions ) ;
39
48
}
40
49
41
- this . panel . webview . html = await this . provideHtmlContent ( node ) ;
50
+ const description : IDescription = this . parseDescription ( descString , node ) ;
51
+ this . panel . webview . html = this . getWebViewContent ( description ) ;
42
52
this . panel . title = `${ node . name } : Preview` ;
43
- this . panel . reveal ( ) ;
53
+ this . panel . reveal ( ViewColumn . One ) ;
44
54
}
45
55
46
56
public dispose ( ) : void {
@@ -49,21 +59,35 @@ class LeetCodePreviewProvider implements Disposable {
49
59
}
50
60
}
51
61
52
- public async provideHtmlContent ( node : IProblem ) : Promise < string > {
53
- return await this . renderHTML ( node ) ;
62
+ private parseDescription ( descString : string , problem : IProblem ) : IDescription {
63
+ const [
64
+ /* title */ , ,
65
+ url , ,
66
+ /* tags */ , ,
67
+ /* langs */ , ,
68
+ category ,
69
+ difficulty ,
70
+ accepted ,
71
+ submissions ,
72
+ /* testcase */ , ,
73
+ ...body
74
+ ] = descString . split ( "\n" ) ;
75
+ return {
76
+ title : problem . name ,
77
+ url,
78
+ tags : problem . tags ,
79
+ companies : problem . companies ,
80
+ category : category . slice ( 2 ) ,
81
+ difficulty : difficulty . slice ( 2 ) ,
82
+ accepted : accepted . split ( ": " ) [ 1 ] ,
83
+ submissions : submissions . split ( ": " ) [ 1 ] ,
84
+ body : body . join ( "\n" ) . replace ( / < p r e > \s * ( [ ^ ] + ?) \s * < \/ p r e > / g, "<pre><code>$1</code></pre>" ) ,
85
+ } ;
54
86
}
55
87
56
- private async renderHTML ( node : IProblem ) : Promise < string > {
57
- const description : string = await leetCodeExecutor . getDescription ( node ) ;
58
- const descriptionHTML : string = description . replace ( / \n / g, "<br>" ) ;
59
- const htmlTemplate : string = `
60
- <!DOCTYPE html>
61
- <html>
62
- <head>
63
- <meta charset="UTF-8">
64
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
65
- <title>Preview Problem</title>
66
- </head>
88
+ private getWebViewContent ( desc : IDescription ) : string {
89
+ const mdStyles : string = markdownEngine . getStylesHTML ( ) ;
90
+ const buttonStyle : string = `
67
91
<style>
68
92
#solve {
69
93
position: fixed;
@@ -82,31 +106,75 @@ class LeetCodePreviewProvider implements Disposable {
82
106
border: 0;
83
107
}
84
108
</style>
109
+ ` ;
110
+ const { title, url, category, difficulty, accepted, submissions, body } = desc ;
111
+ const head : string = markdownEngine . render ( `# [${ title } ](${ url } )` ) ;
112
+ const info : string = markdownEngine . render ( [
113
+ `| Category | Difficulty | Accepted | Submissions |` ,
114
+ `| :------: | :--------: | :------: | :---------: |` ,
115
+ `| ${ category } | ${ difficulty } | ${ accepted } | ${ submissions } |` ,
116
+ ] . join ( "\n" ) ) ;
117
+ const tags : string = [
118
+ `<details>` ,
119
+ `<summary><strong>Tags</strong></summary>` ,
120
+ markdownEngine . render (
121
+ desc . tags
122
+ . map ( ( t : string ) => `[\`${ t } \`](https://leetcode.com/tag/${ t } )` )
123
+ . join ( " | " ) ,
124
+ ) ,
125
+ `</details>` ,
126
+ ] . join ( "\n" ) ;
127
+ const companies : string = [
128
+ `<details>` ,
129
+ `<summary><strong>Companies</strong></summary>` ,
130
+ markdownEngine . render (
131
+ desc . companies
132
+ . map ( ( c : string ) => `\`${ c } \`` )
133
+ . join ( " | " ) ,
134
+ ) ,
135
+ `</details>` ,
136
+ ] . join ( "\n" ) ;
137
+ return `
138
+ <!DOCTYPE html>
139
+ <html>
140
+ <head>
141
+ ${ mdStyles }
142
+ ${ buttonStyle }
143
+ </head>
85
144
<body>
86
- <div >
87
- ${ descriptionHTML }
88
- </div>
145
+ ${ head }
146
+ ${ info }
147
+ ${ tags }
148
+ ${ companies }
149
+ ${ body }
89
150
<button id="solve">Code Now</button>
90
151
<script>
91
- (function() {
92
- const vscode = acquireVsCodeApi();
93
- let button = document.getElementById('solve');
94
- button.onclick = solveHandler;
95
- function solveHandler() {
96
- vscode.postMessage({
97
- command: 'ShowProblem',
98
- });
99
- }
100
- }());
152
+ const vscode = acquireVsCodeApi();
153
+ const button = document.getElementById('solve');
154
+ button.onclick = () => vscode.postMessage({
155
+ command: 'ShowProblem',
156
+ });
101
157
</script>
102
158
</body>
103
- </html>
159
+ </html>
104
160
` ;
105
- return htmlTemplate ;
106
161
}
107
162
108
163
}
109
- export interface IWebViewMessage {
164
+
165
+ interface IDescription {
166
+ title : string ;
167
+ url : string ;
168
+ tags : string [ ] ;
169
+ companies : string [ ] ;
170
+ category : string ;
171
+ difficulty : string ;
172
+ accepted : string ;
173
+ submissions : string ;
174
+ body : string ;
175
+ }
176
+
177
+ interface IWebViewMessage {
110
178
command : string ;
111
179
}
112
180
0 commit comments