3
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
4
*--------------------------------------------------------------------------------------------*/
5
5
6
- import fetch from 'node-fetch' ;
6
+ import fetch , { Response } from 'node-fetch' ;
7
7
import * as vscode from 'vscode' ;
8
8
import { load } from 'js-yaml' ;
9
+ import { CacheHelper } from './common/cache' ;
9
10
10
11
const LAST_READ_RELEASE_NOTES_ID = 'gitpod.lastReadReleaseNotesId' ;
11
12
12
13
export function registerReleaseNotesView ( context : vscode . ExtensionContext ) {
14
+ const cacheHelper = new CacheHelper ( context ) ;
13
15
14
16
async function shouldShowReleaseNotes ( lastReadId : string | undefined ) {
15
- const releaseId = await getLastPublish ( ) ;
17
+ const releaseId = await getLastPublish ( cacheHelper ) ;
16
18
console . log ( `gitpod release notes lastReadId: ${ lastReadId } , latestReleaseId: ${ releaseId } ` ) ;
17
19
return releaseId !== lastReadId ;
18
20
}
19
21
20
22
context . subscriptions . push (
21
23
vscode . commands . registerCommand ( 'gitpod.showReleaseNotes' , ( ) => {
22
- ReleaseNotesPanel . createOrShow ( context ) ;
24
+ ReleaseNotesPanel . createOrShow ( context , cacheHelper ) ;
23
25
} )
24
26
) ;
25
27
@@ -29,18 +31,37 @@ export function registerReleaseNotesView(context: vscode.ExtensionContext) {
29
31
const lastReadId = context . globalState . get < string > ( LAST_READ_RELEASE_NOTES_ID ) ;
30
32
shouldShowReleaseNotes ( lastReadId ) . then ( shouldShow => {
31
33
if ( shouldShow ) {
32
- ReleaseNotesPanel . createOrShow ( context ) ;
34
+ ReleaseNotesPanel . createOrShow ( context , cacheHelper ) ;
33
35
}
34
36
} ) ;
35
37
}
36
38
37
- async function getLastPublish ( ) {
38
- const resp = await fetch ( ` ${ websiteHost } /changelog/latest` ) ;
39
- if ( ! resp . ok ) {
40
- throw new Error ( `Getting latest releaseId failed: ${ resp . statusText } ` ) ;
39
+ function getResponseCacheTime ( resp : Response ) {
40
+ const v = resp . headers . get ( 'Cache-Control' ) ;
41
+ if ( ! v ) {
42
+ return undefined ;
41
43
}
42
- const { releaseId } = JSON . parse ( await resp . text ( ) ) ;
43
- return releaseId as string ;
44
+ const t = / m a x - a g e = ( \d + ) / . exec ( v ) ;
45
+ if ( ! t ) {
46
+ return undefined ;
47
+ }
48
+ return Number ( t [ 1 ] ) ;
49
+ }
50
+
51
+ async function getLastPublish ( cacheHelper : CacheHelper ) {
52
+ const url = `${ websiteHost } /changelog/latest` ;
53
+ return cacheHelper . handy ( url , async ( ) => {
54
+ const resp = await fetch ( url ) ;
55
+ if ( ! resp . ok ) {
56
+ throw new Error ( `Getting latest releaseId failed: ${ resp . statusText } ` ) ;
57
+ }
58
+ const { releaseId } = JSON . parse ( await resp . text ( ) ) ;
59
+ return {
60
+ value : releaseId as string ,
61
+ ttl : getResponseCacheTime ( resp ) ,
62
+ } ;
63
+ } ) ;
64
+
44
65
}
45
66
46
67
const websiteHost = 'https://www.gitpod.io' ;
@@ -53,11 +74,18 @@ class ReleaseNotesPanel {
53
74
private _disposables : vscode . Disposable [ ] = [ ] ;
54
75
55
76
private async loadChangelog ( releaseId : string ) {
56
- const resp = await fetch ( `${ websiteHost } /changelog/raw-markdown?releaseId=${ releaseId } ` ) ;
57
- if ( ! resp . ok ) {
58
- throw new Error ( `Getting raw markdown content failed: ${ resp . statusText } ` ) ;
59
- }
60
- const md = await resp . text ( ) ;
77
+ const url = `${ websiteHost } /changelog/raw-markdown?releaseId=${ releaseId } ` ;
78
+ const md = await this . cacheHelper . handy ( url , async ( ) => {
79
+ const resp = await fetch ( url ) ;
80
+ if ( ! resp . ok ) {
81
+ throw new Error ( `Getting raw markdown content failed: ${ resp . statusText } ` ) ;
82
+ }
83
+ const md = await resp . text ( ) ;
84
+ return {
85
+ value : md ,
86
+ ttl : getResponseCacheTime ( resp ) ,
87
+ } ;
88
+ } ) ;
61
89
62
90
const parseInfo = ( md : string ) => {
63
91
if ( ! md . startsWith ( '---' ) ) {
@@ -96,7 +124,7 @@ class ReleaseNotesPanel {
96
124
97
125
public async updateHtml ( releaseId ?: string ) {
98
126
if ( ! releaseId ) {
99
- releaseId = await getLastPublish ( ) ;
127
+ releaseId = await getLastPublish ( this . cacheHelper ) ;
100
128
}
101
129
const mdContent = await this . loadChangelog ( releaseId ) ;
102
130
const html = await vscode . commands . executeCommand ( 'markdown.api.render' , mdContent ) as string ;
@@ -120,7 +148,7 @@ class ReleaseNotesPanel {
120
148
}
121
149
}
122
150
123
- public static createOrShow ( context : vscode . ExtensionContext ) {
151
+ public static createOrShow ( context : vscode . ExtensionContext , cacheHelper : CacheHelper ) {
124
152
const column = vscode . window . activeTextEditor
125
153
? vscode . window . activeTextEditor . viewColumn
126
154
: undefined ;
@@ -137,15 +165,16 @@ class ReleaseNotesPanel {
137
165
{ enableScripts : true } ,
138
166
) ;
139
167
140
- ReleaseNotesPanel . currentPanel = new ReleaseNotesPanel ( context , panel ) ;
168
+ ReleaseNotesPanel . currentPanel = new ReleaseNotesPanel ( context , cacheHelper , panel ) ;
141
169
}
142
170
143
- public static revive ( context : vscode . ExtensionContext , panel : vscode . WebviewPanel ) {
144
- ReleaseNotesPanel . currentPanel = new ReleaseNotesPanel ( context , panel ) ;
171
+ public static revive ( context : vscode . ExtensionContext , cacheHelper : CacheHelper , panel : vscode . WebviewPanel ) {
172
+ ReleaseNotesPanel . currentPanel = new ReleaseNotesPanel ( context , cacheHelper , panel ) ;
145
173
}
146
174
147
175
private constructor (
148
176
private readonly context : vscode . ExtensionContext ,
177
+ private readonly cacheHelper : CacheHelper ,
149
178
panel : vscode . WebviewPanel
150
179
) {
151
180
this . lastReadId = this . context . globalState . get < string > ( LAST_READ_RELEASE_NOTES_ID ) ;
0 commit comments