Feat/478 webview api (#482)

This commit is contained in:
Alessio Occhipinti 2020-06-25 10:34:19 +02:00 committed by GitHub
parent 3c09e09b25
commit 04d220eda7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 408 additions and 577 deletions

View file

@ -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

View file

@ -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": {

View file

@ -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);
}
};

View file

@ -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();

View file

@ -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 {};
}
}

View file

@ -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) {

View file

@ -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>;
}
}

861
yarn.lock

File diff suppressed because it is too large Load diff