@@ -11,14 +11,16 @@ import * as os from 'os';
11
11
import * as cp from 'child_process' ;
12
12
import * as tmp from 'tmp' ;
13
13
import { LanguageClient , LanguageClientOptions , RequestType , NotificationType , TextDocumentIdentifier , TextDocument , ExecuteCommandRequest } from 'vscode-languageclient' ;
14
- import { Uri , Event , TextDocumentContentProvider , ViewColumn , EventEmitter , window , QuickPickOptions , ExtensionContext , env , WorkspaceConfiguration } from 'vscode'
14
+ import { Uri , Event , TextDocumentContentProvider , ViewColumn , EventEmitter , window , QuickPickOptions , ExtensionContext , env , WorkspaceConfiguration } from 'vscode' ;
15
15
import * as which from 'which' ;
16
16
import * as util from 'util' ;
17
-
17
+ import fetch , { Response } from 'node-fetch' ;
18
+ import { getOrd } from 'fp-ts/lib/Array' ;
19
+ import { ordNumber } from 'fp-ts/lib/Ord' ;
18
20
19
21
let damlRoot : string = path . join ( os . homedir ( ) , '.daml' ) ;
20
22
21
- let versionContextKey = 'version'
23
+ const versionContextKey = 'version'
22
24
23
25
var damlLanguageClient : LanguageClient ;
24
26
// Extension activation
@@ -31,8 +33,8 @@ export async function activate(context: vscode.ExtensionContext) {
31
33
// Get telemetry consent
32
34
const consent = getTelemetryConsent ( config , context ) ;
33
35
34
- // Check extension version to publish release notes on updates
35
- checkVersion ( context ) ;
36
+ // Check extension version to display release notes on updates
37
+ showReleaseNotesIfNewVersion ( context ) ;
36
38
37
39
damlLanguageClient = createLanguageClient ( config , await consent ) ;
38
40
damlLanguageClient . registerProposedFeatures ( ) ;
@@ -97,17 +99,55 @@ export async function activate(context: vscode.ExtensionContext) {
97
99
}
98
100
99
101
// Compare the extension version with the one stored in the global state.
100
- // This will be used to show release notes when the version has changed.
101
- async function checkVersion ( context : ExtensionContext ) {
102
- let packageFile = path . join ( context . extensionPath , 'package.json' ) ;
103
- let packageData = await util . promisify ( fs . readFile ) ( packageFile , "utf8" ) ;
104
- let extensionVersion = JSON . parse ( packageData ) . version ;
105
- let recordedVersion = context . globalState . get ( versionContextKey ) ;
106
- if ( ! recordedVersion || recordedVersion != extensionVersion ) {
102
+ // If they are different, we assume the user has updated the extension and
103
+ // we display the release notes for the new SDK release in a new tab.
104
+ // This should only occur the first time the user uses the extension after
105
+ // an update.
106
+ async function showReleaseNotesIfNewVersion ( context : ExtensionContext ) {
107
+ const packageFile = path . join ( context . extensionPath , 'package.json' ) ;
108
+ const packageData = await util . promisify ( fs . readFile ) ( packageFile , "utf8" ) ;
109
+ const extensionVersion = JSON . parse ( packageData ) . version ;
110
+ const recordedVersion = String ( context . globalState . get ( versionContextKey ) ) ;
111
+ if ( ! recordedVersion || checkVersionUpgrade ( recordedVersion , extensionVersion ) ) {
112
+ // We have a new version of the extension so show the release notes
113
+ // and update the current version so we don't show them again until
114
+ // the next update.
115
+ showReleaseNotes ( extensionVersion ) ;
107
116
await context . globalState . update ( versionContextKey , extensionVersion ) ;
108
117
}
109
118
}
110
119
120
+ // Check that `version2` is an upgrade from `version1`,
121
+ // i.e. that the components of the version number have increased
122
+ // (checked from major to minor version numbers).
123
+ function checkVersionUpgrade ( version1 : string , version2 : string ) {
124
+ const comps1 = version1 . split ( "." ) . map ( Number ) ;
125
+ const comps2 = version2 . split ( "." ) . map ( Number ) ;
126
+ const o = getOrd ( ordNumber ) ;
127
+ return o . compare ( comps2 , comps1 ) > 0 ;
128
+ }
129
+
130
+ // Show the release notes from the DAML Blog.
131
+ // We display the HTML in a new editor tab using a "webview":
132
+ // https://code.visualstudio.com/api/extension-guides/webview
133
+ async function showReleaseNotes ( version : string ) {
134
+ const releaseNotesUrl = 'https://blog.daml.com/release-notes/' ;
135
+ if ( version ) {
136
+ const url = releaseNotesUrl + version ;
137
+ fetch ( url ) . then ( async ( result : Response ) => {
138
+ if ( result . ok ) {
139
+ const panel = vscode . window . createWebviewPanel (
140
+ 'releaseNotes' , // Identifies the type of the webview. Used internally
141
+ `Release Notes for DAML SDK ${ version } ` , // Title of the panel displayed to the user
142
+ vscode . ViewColumn . One , // Editor column to show the new webview panel in
143
+ { } // No webview options for now
144
+ ) ;
145
+ panel . webview . html = await result . text ( ) ;
146
+ }
147
+ } ) ;
148
+ }
149
+ }
150
+
111
151
function getViewColumnForShowResource ( ) : ViewColumn {
112
152
const active = vscode . window . activeTextEditor ;
113
153
if ( ! active || ! active . viewColumn ) { return ViewColumn . One ; }
0 commit comments