Feat/478 webview api (#482)
This commit is contained in:
parent
3c09e09b25
commit
04d220eda7
8 changed files with 408 additions and 577 deletions
|
@ -5,8 +5,7 @@
|
|||
],
|
||||
"rules": {
|
||||
"@typescript-eslint/indent": ["error", 2, { "SwitchCase": 1 }],
|
||||
"@typescript-eslint/member-naming": 0,
|
||||
"@typescript-eslint/interface-name-prefix": ["error", { "prefixWithI": "always" }]
|
||||
"@typescript-eslint/member-naming": 0
|
||||
},
|
||||
"env": {
|
||||
"browser": true
|
||||
|
|
24
package.json
24
package.json
|
@ -170,17 +170,18 @@
|
|||
"devDependencies": {
|
||||
"@moxer/vscode-theme-generator": "1.19.0",
|
||||
"@types/browserify": "12.0.36",
|
||||
"@types/rimraf": "2.0.2",
|
||||
"@typescript-eslint/eslint-plugin": "2.12.0",
|
||||
"@typescript-eslint/parser": "2.12.0",
|
||||
"browserify": "16.2.2",
|
||||
"eslint": "6.7.2",
|
||||
"eslint-config-xo-space": "0.22.0",
|
||||
"eslint-config-xo-typescript": "0.23.0",
|
||||
"fs-extra": "8.1.0",
|
||||
"@types/fs-extra": "8.1.0",
|
||||
"@types/rimraf": "3.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "3.3.0",
|
||||
"@typescript-eslint/parser": "3.3.0",
|
||||
"browserify": "16.5.1",
|
||||
"eslint": "7.2.0",
|
||||
"eslint-config-xo-space": "0.25.0",
|
||||
"eslint-config-xo-typescript": "0.31.0",
|
||||
"fs-extra": "9.0.1",
|
||||
"ncp": "2.0.0",
|
||||
"typescript": "3.7.4",
|
||||
"vscode": "1.1.36"
|
||||
"typescript": "3.9.5",
|
||||
"vscode": "1.1.37"
|
||||
},
|
||||
"__metadata": {
|
||||
"id": "dffaf5a1-2219-434b-9d87-cb586fd59260",
|
||||
|
@ -188,8 +189,7 @@
|
|||
"publisherId": "e41388a1-a892-4c1e-940b-1e7c1bf43c97"
|
||||
},
|
||||
"dependencies": {
|
||||
"@sanity/client": "0.147.3",
|
||||
"@types/fs-extra": "8.0.1",
|
||||
"@sanity/client": "1.149.16",
|
||||
"opencollective": "1.0.3"
|
||||
},
|
||||
"collective": {
|
||||
|
|
|
@ -24,10 +24,10 @@ const getThemeColorCustomizationsConfig = (accentColor?: string): Record<string,
|
|||
|
||||
const updateColorCustomizationsConfig = async (config: any): Promise<boolean> => {
|
||||
try {
|
||||
workspace.getConfiguration().update('workbench.colorCustomizations', config, true);
|
||||
await workspace.getConfiguration().update('workbench.colorCustomizations', config, true);
|
||||
return true;
|
||||
} catch (error) {
|
||||
window.showErrorMessage(error);
|
||||
await window.showErrorMessage(error);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ export interface IExtensionManager {
|
|||
init: () => Promise<void>;
|
||||
getPackageJSON: () => Record<string, any>;
|
||||
getConfig: () => MaterialThemeConfig;
|
||||
getInstallationType: () => {};
|
||||
getInstallationType: () => Record<string, unknown>;
|
||||
updateConfig: (config: Partial<MaterialThemeConfig>) => Promise<void>;
|
||||
}
|
||||
|
||||
|
@ -50,6 +50,32 @@ class ExtensionManager implements IExtensionManager {
|
|||
await workspace.fs.writeFile(this.configFileUri, Buffer.from(JSON.stringify(newConfig), 'utf-8'));
|
||||
}
|
||||
|
||||
async init(): Promise<void> {
|
||||
try {
|
||||
const packageJSON = this.getPackageJSON();
|
||||
const userConfig = await this.getUserConfig();
|
||||
this.installationType = {
|
||||
update: userConfig && this.isVersionUpdate(userConfig),
|
||||
firstInstall: !userConfig
|
||||
};
|
||||
|
||||
const configBuffer = await workspace.fs.readFile(this.configFileUri);
|
||||
const configContent = Buffer.from(configBuffer).toString('utf8');
|
||||
|
||||
this.configJSON = JSON.parse(configContent) as MaterialThemeConfig;
|
||||
|
||||
const userConfigUpdate = {...this.configJSON, changelog: {lastversion: packageJSON.version}};
|
||||
await workspace.fs.writeFile(
|
||||
this.userConfigFileUri,
|
||||
Buffer.from(JSON.stringify(userConfigUpdate), 'utf-8')
|
||||
);
|
||||
} catch (error) {
|
||||
this.configJSON = {accentsProperties: {}, accents: {}};
|
||||
await window
|
||||
.showErrorMessage(`Material Theme: there was an error while loading the configuration. Please retry or open an issue: ${String(error)}`);
|
||||
}
|
||||
}
|
||||
|
||||
private isVersionUpdate(userConfig: MaterialThemeConfig): boolean {
|
||||
const splitVersion = (input: string): {major: number; minor: number; patch: number} => {
|
||||
const [major, minor, patch] = input.split('.').map(i => parseInt(i, 10));
|
||||
|
@ -77,32 +103,6 @@ class ExtensionManager implements IExtensionManager {
|
|||
return JSON.parse(configContent) as MaterialThemeConfig;
|
||||
} catch {}
|
||||
}
|
||||
|
||||
async init(): Promise<void> {
|
||||
try {
|
||||
const packageJSON = this.getPackageJSON();
|
||||
const userConfig = await this.getUserConfig();
|
||||
this.installationType = {
|
||||
update: userConfig && this.isVersionUpdate(userConfig),
|
||||
firstInstall: !userConfig
|
||||
};
|
||||
|
||||
const configBuffer = await workspace.fs.readFile(this.configFileUri);
|
||||
const configContent = Buffer.from(configBuffer).toString('utf8');
|
||||
|
||||
this.configJSON = JSON.parse(configContent) as MaterialThemeConfig;
|
||||
|
||||
const userConfigUpdate = {...this.configJSON, changelog: {lastversion: packageJSON.version}};
|
||||
await workspace.fs.writeFile(
|
||||
this.userConfigFileUri,
|
||||
Buffer.from(JSON.stringify(userConfigUpdate), 'utf-8')
|
||||
);
|
||||
} catch (error) {
|
||||
this.configJSON = {accentsProperties: {}, accents: {}};
|
||||
window
|
||||
.showErrorMessage(`Material Theme: there was an error while loading the configuration. Please retry or open an issue: ${String(error)}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const extensionManager = new ExtensionManager();
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import {WebviewController} from './Webview';
|
||||
|
||||
export class ReleaseNotesWebview extends WebviewController<{}> {
|
||||
export class ReleaseNotesWebview extends WebviewController<Record<string, unknown>> {
|
||||
get filename(): string {
|
||||
return 'release-notes.html';
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ export class ReleaseNotesWebview extends WebviewController<{}> {
|
|||
* This will be called by the WebviewController when init the view
|
||||
* passing as `window.bootstrap` to the view.
|
||||
*/
|
||||
getBootstrap(): {} {
|
||||
getBootstrap(): Record<string, unknown> {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,17 +36,10 @@ export abstract class WebviewController<TBootstrap> extends Disposable {
|
|||
async show(): Promise<void> {
|
||||
const html = await this.getHtml();
|
||||
|
||||
const rootPath = Uri
|
||||
.file(this.context.asAbsolutePath('./build'))
|
||||
.with({scheme: 'vscode-resource'}).toString();
|
||||
|
||||
// Replace placeholders in html content for assets and adding configurations as `window.bootstrap`
|
||||
const fullHtml = html
|
||||
.replace(/{{root}}/g, rootPath)
|
||||
.replace('\'{{bootstrap}}\'', JSON.stringify(this.getBootstrap()));
|
||||
|
||||
// If panel already opened just reveal
|
||||
if (this.panel !== undefined) {
|
||||
// Replace placeholders in html content for assets and adding configurations as `window.bootstrap`
|
||||
const fullHtml = this.replaceInPanel(html);
|
||||
this.panel.webview.html = fullHtml;
|
||||
return this.panel.reveal(ViewColumn.Active);
|
||||
}
|
||||
|
@ -71,6 +64,9 @@ export abstract class WebviewController<TBootstrap> extends Disposable {
|
|||
this.panel.webview.onDidReceiveMessage(this.onMessageReceived, this)
|
||||
);
|
||||
|
||||
// Replace placeholders in html content for assets and adding configurations as `window.bootstrap`
|
||||
const fullHtml = this.replaceInPanel(html);
|
||||
|
||||
this.panel.webview.html = fullHtml;
|
||||
}
|
||||
|
||||
|
@ -90,6 +86,16 @@ export abstract class WebviewController<TBootstrap> extends Disposable {
|
|||
}
|
||||
}
|
||||
|
||||
private replaceInPanel(html: string): string {
|
||||
// Replace placeholders in html content for assets and adding configurations as `window.bootstrap`
|
||||
const fullHtml = html
|
||||
.replace(/{{root}}/g, this.panel.webview.asWebviewUri(Uri.file(this.context.asAbsolutePath('./build'))).toString())
|
||||
.replace(/{{cspSource}}/g, this.panel.webview.cspSource)
|
||||
.replace('\'{{bootstrap}}\'', JSON.stringify(this.getBootstrap()));
|
||||
|
||||
return fullHtml;
|
||||
}
|
||||
|
||||
private async getHtml(): Promise<string> {
|
||||
const doc = await Workspace
|
||||
.openTextDocument(this.context.asAbsolutePath(path.join('build/ui', this.filename)));
|
||||
|
@ -127,7 +133,7 @@ export abstract class WebviewController<TBootstrap> extends Disposable {
|
|||
this.panel = undefined;
|
||||
}
|
||||
|
||||
private async onViewStateChanged(event: WebviewPanelOnDidChangeViewStateEvent): Promise<boolean | void> {
|
||||
private async onViewStateChanged(event: WebviewPanelOnDidChangeViewStateEvent): Promise<void> {
|
||||
console.log('WebviewEditor.onViewStateChanged', event.webviewPanel.visible);
|
||||
|
||||
if (!this.invalidateOnVisible || !event.webviewPanel.visible) {
|
||||
|
|
|
@ -19,7 +19,7 @@ export interface IPostNormalized {
|
|||
}
|
||||
export interface ISettingsChangedMessage {
|
||||
type: 'settingsChanged';
|
||||
config: {};
|
||||
config: Record<string, unknown>;
|
||||
}
|
||||
|
||||
export interface ISaveSettingsMessage {
|
||||
|
@ -36,18 +36,17 @@ export type Message = ISaveSettingsMessage | ISettingsChangedMessage;
|
|||
export type Invalidates = 'all' | 'config' | undefined;
|
||||
|
||||
export interface IBootstrap {
|
||||
config: {};
|
||||
config: Record<string, unknown>;
|
||||
}
|
||||
|
||||
export interface ISettingsBootstrap extends IBootstrap {
|
||||
scope: 'user' | 'workspace';
|
||||
scopes: Array<['user' | 'workspace', string]>;
|
||||
defaults: {};
|
||||
defaults: Record<string, unknown>;
|
||||
}
|
||||
|
||||
declare global {
|
||||
// eslint-disable-next-line @typescript-eslint/interface-name-prefix
|
||||
interface Window {
|
||||
bootstrap: IBootstrap | ISettingsBootstrap | {};
|
||||
bootstrap: IBootstrap | ISettingsBootstrap | Record<string, unknown>;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue