diff --git a/.gitignore b/.gitignore index 59f2072..d82a930 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ node_modules/ /ui/ build dist +user.material-theme.config.json diff --git a/env.ts b/env.ts deleted file mode 100644 index 83f674c..0000000 --- a/env.ts +++ /dev/null @@ -1,5 +0,0 @@ -import * as path from 'path'; - -export const SRC_FOLDER_PATH = path.resolve('./src'); -export const BUILD_FOLDER_PATH = path.resolve('./build'); -export const TS_BUILD_FOLDER_PATH = path.resolve('./dist'); diff --git a/material-theme.config.json b/material-theme.config.json new file mode 100644 index 0000000..7b64def --- /dev/null +++ b/material-theme.config.json @@ -0,0 +1,109 @@ +{ + "accents": { + "Acid Lime": "#C6FF00", + "Blue": "#2979FF", + "Breaking Bad": "#388E3C", + "Bright Teal": "#64FFDA", + "Cyan": "#00BCD4", + "Graphite": "#616161", + "Indigo": "#5C6BC0", + "Lime": "#7CB342", + "Orange": "#FF7042", + "Pink": "#FF4081", + "Purple": "#AB47BC", + "Red": "#E57373", + "Sky": "#84FFFF", + "Tomato": "#F44336", + "Teal": "#80CBC4", + "Yellow": "#FFA000" + }, + "accentsProperties": { + "activityBarBadge.background": { + "alpha": 100, + "value": null + }, + "list.activeSelectionForeground": { + "alpha": 100, + "value": null + }, + "list.inactiveSelectionForeground": { + "alpha": 100, + "value": null + }, + "list.highlightForeground": { + "alpha": 100, + "value": null + }, + "scrollbarSlider.activeBackground": { + "alpha": 50, + "value": null + }, + "editorSuggestWidget.highlightForeground": { + "alpha": 100, + "value": null + }, + "textLink.foreground": { + "alpha": 100, + "value": null + }, + "progressBar.background": { + "alpha": 100, + "value": null + }, + "pickerGroup.foreground": { + "alpha": 100, + "value": null + }, + "tab.activeBorder": { + "alpha": 100, + "value": null + }, + "notificationLink.foreground": { + "alpha": 100, + "value": null + }, + "editorWidget.resizeBorder": { + "alpha": 100, + "value": null + }, + "editorWidget.border": { + "alpha": 100, + "value": null + }, + "settings.modifiedItemIndicator": { + "alpha": 100, + "value": null + }, + "settings.headerForeground": { + "alpha": 100, + "value": null + }, + "panelTitle.activeBorder": { + "alpha": 100, + "value": null + }, + "breadcrumb.activeSelectionForeground": { + "alpha": 100, + "value": null + }, + "menu.selectionForeground": { + "alpha": 100, + "value": null + }, + "menubar.selectionForeground": { + "alpha": 100, + "value": null + }, + "editor.findMatchBorder": { + "alpha": 100, + "value": null + }, + "selection.background": { + "alpha": 40, + "value": null + } + }, + "changelog": { + "lastversion": "30.0.0" + } +} diff --git a/package.json b/package.json index b2cd565..b3894f9 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ }, "engines": { "node": "<=10", - "vscode": ">=1.39.0" + "vscode": ">=1.1.36" }, "scripts": { "build": "yarn cleanup && yarn build:ts && yarn build:generate-themes && yarn build:ui", @@ -29,7 +29,7 @@ "lint": "eslint .", "build:ui": "node dist/scripts/ui/index.js", "build:generate-themes": "node dist/scripts/generator/index.js", - "build:ts": "tsc -p ./tsconfig.json && ncp dist/src/ build", + "build:ts": "tsc -p ./tsconfig.json && ncp dist/src/ build && ncp material-theme.config.json build", "postinstall": "node ./node_modules/vscode/bin/install && opencollective postinstall && tsc -p tsconfig.json" }, "categories": [ diff --git a/scripts/generator/index.ts b/scripts/generator/index.ts index 591e5bb..d10d0ba 100644 --- a/scripts/generator/index.ts +++ b/scripts/generator/index.ts @@ -4,7 +4,7 @@ import * as path from 'path'; import {generateTheme} from '@moxer/vscode-theme-generator'; import {ThemeSetting} from './types'; import {getColorSet} from './color-set'; -import {BUILD_FOLDER_PATH} from '../../env'; +import {BUILD_FOLDER_PATH} from '../../src/env'; const THEME_BUILD_PATH = path.join(BUILD_FOLDER_PATH, 'themes'); const themes = ['default', 'darker', 'lighter', 'ocean', 'palenight']; diff --git a/scripts/ui/index.ts b/scripts/ui/index.ts index 0f30d8e..6c7fd2a 100644 --- a/scripts/ui/index.ts +++ b/scripts/ui/index.ts @@ -2,7 +2,7 @@ import * as fs from 'fs-extra'; import * as path from 'path'; import browserify from 'browserify'; -import {BUILD_FOLDER_PATH, SRC_FOLDER_PATH, TS_BUILD_FOLDER_PATH} from '../../env'; +import {BUILD_FOLDER_PATH, SRC_FOLDER_PATH, TS_BUILD_FOLDER_PATH} from '../../src/env'; const UI_FOLDER_PATH = path.join(SRC_FOLDER_PATH, 'webviews', 'ui'); const UI_JS_FOLDER_PATH = path.join(TS_BUILD_FOLDER_PATH, 'src', 'webviews', 'ui'); @@ -14,7 +14,7 @@ const copyStatics = async (): Promise => { dest: path.join(UI_FOLDER_BUILD_PATH, 'release-notes.html') }, { src: path.join(UI_FOLDER_PATH, 'release-notes', 'style.css'), - dest: path.join(UI_FOLDER_BUILD_PATH, 'style.css') + dest: path.join(UI_FOLDER_BUILD_PATH, 'release-notes.css') }]; return Promise.all(paths.map(async path => fs.copyFile(path.src, path.dest))); diff --git a/src/commands/accents-setter/consts.ts b/src/commands/accents-setter/consts.ts deleted file mode 100644 index ed3b8fc..0000000 --- a/src/commands/accents-setter/consts.ts +++ /dev/null @@ -1,3 +0,0 @@ -export default { - PURGE_KEY: 'Remove accents' -}; diff --git a/src/commands/accents-setter/index.ts b/src/commands/accents-setter/index.ts deleted file mode 100644 index 272f6bd..0000000 --- a/src/commands/accents-setter/index.ts +++ /dev/null @@ -1,67 +0,0 @@ -import * as vscode from 'vscode'; - -import {getDefaultValues, getAccentsProperties} from './../../helpers/fs'; -import consts from './consts'; - -const REGEXP_HEX: RegExp = /^#([0-9A-F]{6}|[0-9A-F]{8})$/i; - -/** - * Assigns colours - */ -const assignColorCustomizations = (colour: string): Object => { - const accentsProperties = getAccentsProperties(); - const newColour = isValidColour(colour) ? colour : undefined; - return Object.keys(accentsProperties).reduce((acc: any, propName) => { - const accent = accentsProperties[propName]; - let colorProp = newColour; - - if (colour && accent.alpha < 100) { - colorProp = `${ colour }${ accent.alpha > 10 ? accent.alpha : `0${ accent.alpha }` }`; - } - - acc[propName] = colorProp; - return acc; - }, {}); -}; - -/** - * Determines if a string is a valid colour - */ -const isValidColour = (colour: string | null | undefined): boolean => - typeof colour === 'string' && REGEXP_HEX.test(colour); - -/** - * Sets workbench options - */ -const setWorkbenchOptions = (config: any): Thenable => - vscode.workspace.getConfiguration().update('workbench.colorCustomizations', config, true) - .then(() => true, reason => vscode.window.showErrorMessage(reason)); -/** - * VSCode command - */ -export default async (accent?: string): Promise => { - const themeConfigCommon = getDefaultValues(); - const config: any = vscode.workspace.getConfiguration().get('workbench.colorCustomizations'); - - switch (accent) { - case consts.PURGE_KEY: { - const newConfig = { - ...config, - ...assignColorCustomizations(undefined) - }; - - return setWorkbenchOptions(newConfig) - .then(() => Promise.resolve(true)); - } - default: { - const newConfig = { - ...config, - ...assignColorCustomizations(themeConfigCommon.accents[accent]) - }; - - return setWorkbenchOptions(newConfig) - .then(() => Boolean(accent)); - } - } - -}; diff --git a/src/commands/accents-setter/quick-pick.ts b/src/commands/accents-setter/quick-pick.ts deleted file mode 100644 index 013c0ff..0000000 --- a/src/commands/accents-setter/quick-pick.ts +++ /dev/null @@ -1,9 +0,0 @@ -import * as vscode from 'vscode'; -import {getDefaultValues} from '../../helpers/fs'; -import consts from './consts'; - -export default async () => { - const themeConfigCommon = getDefaultValues(); - const options: string[] = Object.keys(themeConfigCommon.accents).concat(consts.PURGE_KEY); - return vscode.window.showQuickPick(options); -}; diff --git a/src/commands/index.ts b/src/commands/index.ts index 853732b..d69bbc5 100644 --- a/src/commands/index.ts +++ b/src/commands/index.ts @@ -1,2 +1 @@ -export {default as accentsSetter} from './accents-setter'; -export {default as accentsQuickPick} from './accents-setter/quick-pick'; +export {command as setAccent} from './set-accent'; diff --git a/src/commands/set-accent.ts b/src/commands/set-accent.ts new file mode 100644 index 0000000..303ecf7 --- /dev/null +++ b/src/commands/set-accent.ts @@ -0,0 +1,55 @@ +import {workspace, window} from 'vscode'; +import {extensionManager} from '../core/extension-manager'; +import {settingsManager} from '../core/settings-manager'; + +const PURGE_KEY = 'Remove accents'; + +const isValidColor = (color: string | null | undefined): boolean => + color && /^#([0-9A-F]{6}|[0-9A-F]{8})$/i.test(color); + +const getThemeColorCustomizationsConfig = (accentColor?: string): Record => { + const {accentsProperties} = extensionManager.getConfig(); + const color = isValidColor(accentColor) ? accentColor : undefined; + + const themeColorCustomConfig = Object.keys(accentsProperties).reduce((acc: any, propName) => { + const currentProp = accentsProperties[propName]; + const shouldModify = color && currentProp.alpha < 100; + const colorProp = shouldModify ? `${color}${currentProp.alpha > 10 ? currentProp.alpha : `0${currentProp.alpha}`}` : color; + acc[propName] = colorProp; + return acc; + }, {}); + + return themeColorCustomConfig; +}; + +const updateColorCustomizationsConfig = async (config: any): Promise => { + try { + workspace.getConfiguration().update('workbench.colorCustomizations', config, true); + return true; + } catch (error) { + window.showErrorMessage(error); + } +}; + +const quickPick = async (): Promise => { + const themeConfig = extensionManager.getConfig(); + const options: string[] = Object.keys(themeConfig.accents).concat(PURGE_KEY); + return window.showQuickPick(options); +}; + +export const command = async (): Promise => { + const themeConfig = extensionManager.getConfig(); + const currentColorCustomizationsConfig: any = workspace.getConfiguration().get('workbench.colorCustomizations'); + const accent = await quickPick(); + + const config = accent === PURGE_KEY ? { + ...currentColorCustomizationsConfig, + ...getThemeColorCustomizationsConfig() + } : { + ...currentColorCustomizationsConfig, + ...getThemeColorCustomizationsConfig(themeConfig.accents[accent]) + }; + + await updateColorCustomizationsConfig(config); + await settingsManager.updateSetting('accent', accent); +}; diff --git a/src/consts/files.ts b/src/consts/files.ts deleted file mode 100644 index 63a0935..0000000 --- a/src/consts/files.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * File charset - */ -export const CHARSET: string = 'utf-8'; diff --git a/src/consts/paths.ts b/src/consts/paths.ts deleted file mode 100644 index 395d53b..0000000 --- a/src/consts/paths.ts +++ /dev/null @@ -1,14 +0,0 @@ -import * as path from 'path'; - -import {IPaths} from '../interfaces/ipaths'; - -export const PATHS: IPaths = { - SRC: './src', - THEMES: './out/themes', - UI: './out/ui', - VSIX_SRC_DIR: path.join(__dirname, '../..'), // From "src" dir - VSIX_DIR: path.join(__dirname, '../../..'), // From "out" dir - EXT_DIR: path.join(__dirname, '..') -}; - -export default PATHS; diff --git a/src/core/changelog-manager.ts b/src/core/changelog-manager.ts new file mode 100644 index 0000000..c9b1329 --- /dev/null +++ b/src/core/changelog-manager.ts @@ -0,0 +1,28 @@ +import {window} from 'vscode'; +import {MESSAGES} from '../helpers/messages'; + +type AskMessage = { + message: string; + options: { + ok: string; + cancel: string; + }; +}; + +class ChangelogManager { + private readonly askMessage: AskMessage; + + constructor(message: AskMessage) { + this.askMessage = message; + } + + async askShowChangelog(): Promise { + return await window.showInformationMessage( + this.askMessage.message, + this.askMessage.options.ok, + this.askMessage.options.cancel + ) === this.askMessage.options.ok; + } +} + +export const changelogManager = new ChangelogManager(MESSAGES.CHANGELOG); diff --git a/src/core/extension-manager.ts b/src/core/extension-manager.ts new file mode 100644 index 0000000..230b8a3 --- /dev/null +++ b/src/core/extension-manager.ts @@ -0,0 +1,103 @@ +import {extensions, workspace, window, Uri} from 'vscode'; +import {posix} from 'path'; +import {CONFIG_FILE_NAME, USER_CONFIG_FILE_NAME, MATERIAL_THEME_EXT_ID} from '../env'; + +type MaterialThemeConfig = { + accents: Record; + accentsProperties: Record; + changelog?: { lastversion?: string }; +}; + +type InstallationType = { + firstInstall: boolean; + update: boolean; +}; + +export interface IExtensionManager { + getPackageJSON: () => Record; + getConfig: () => MaterialThemeConfig; + getInstallationType: () => {}; + updateConfig: (config: Partial) => Promise; +} + +class ExtensionManager implements IExtensionManager { + installationType: InstallationType; + private readonly configFileUri: Uri; + private readonly userConfigFileUri: Uri; + private configJSON: MaterialThemeConfig; + + constructor() { + const extensionFolderUri = Uri.file(extensions.getExtension(MATERIAL_THEME_EXT_ID).extensionPath); + this.configFileUri = extensionFolderUri.with({path: posix.join(extensionFolderUri.path, CONFIG_FILE_NAME)}); + this.userConfigFileUri = extensionFolderUri.with({path: posix.join(extensionFolderUri.path, USER_CONFIG_FILE_NAME)}); + this.init(); + } + + getPackageJSON(): Record { + return extensions.getExtension(MATERIAL_THEME_EXT_ID).packageJSON; + } + + getConfig(): MaterialThemeConfig { + return this.configJSON; + } + + getInstallationType(): InstallationType { + return this.installationType; + } + + async updateConfig(config: Partial): Promise { + const newConfig = {...this.configJSON, ...config}; + await workspace.fs.writeFile(this.configFileUri, Buffer.from(JSON.stringify(newConfig), 'utf-8')); + } + + 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)); + return {major, minor, patch}; + }; + + const packageJSON = this.getPackageJSON(); + + const versionCurrent = splitVersion(packageJSON.version); + const versionOld = splitVersion(userConfig.changelog.lastversion); + + const update = ( + versionCurrent.major > versionOld.major || + versionCurrent.minor > versionOld.minor || + versionCurrent.patch > versionOld.patch + ); + + return update; + } + + private async getUserConfig(): Promise { + try { + const configBuffer = await workspace.fs.readFile(this.userConfigFileUri); + const configContent = Buffer.from(configBuffer).toString('utf8'); + return JSON.parse(configContent) as MaterialThemeConfig; + } catch {} + } + + private async init(): Promise { + try { + 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'); + + await workspace.fs.writeFile(this.userConfigFileUri, configBuffer); + + this.configJSON = JSON.parse(configContent) as MaterialThemeConfig; + } 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(); diff --git a/src/core/settings-manager.ts b/src/core/settings-manager.ts new file mode 100644 index 0000000..ff5074b --- /dev/null +++ b/src/core/settings-manager.ts @@ -0,0 +1,28 @@ + +import {workspace} from 'vscode'; + +type ThemeCustomSettings = { + accent?: string; +}; + +export interface ISettingsManager { + getSettings: () => ThemeCustomSettings; +} + +class SettingsManager implements ISettingsManager { + private readonly customSettings: ThemeCustomSettings; + + constructor() { + this.customSettings = workspace.getConfiguration().get('materialTheme', {}); + } + + getSettings(): ThemeCustomSettings { + return this.customSettings; + } + + async updateSetting(key: keyof ThemeCustomSettings, value: string): Promise { + await workspace.getConfiguration().update(`materialTheme.${key}`, value, true); + } +} + +export const settingsManager = new SettingsManager(); diff --git a/src/env.ts b/src/env.ts new file mode 100644 index 0000000..f45d48c --- /dev/null +++ b/src/env.ts @@ -0,0 +1,8 @@ +import * as path from 'path'; + +export const SRC_FOLDER_PATH = path.resolve('./src'); +export const BUILD_FOLDER_PATH = path.resolve('./build'); +export const TS_BUILD_FOLDER_PATH = path.resolve('./dist'); +export const CONFIG_FILE_NAME = 'material-theme.config.json'; +export const USER_CONFIG_FILE_NAME = 'user.material-theme.config.json'; +export const MATERIAL_THEME_EXT_ID = 'equinusocio.vsc-material-theme'; diff --git a/src/helpers/check-installation.ts b/src/helpers/check-installation.ts deleted file mode 100644 index fc52488..0000000 --- a/src/helpers/check-installation.ts +++ /dev/null @@ -1,34 +0,0 @@ -import {getDefaultValues, getPackageJSON} from './fs'; -import {IInstallationType} from '../interfaces/iinstallation-type'; - -const splitVersion = (input: string): {major: number; minor: number; patch: number} => { - const [major, minor, patch] = input.split('.').map(i => parseInt(i, 10)); - return {major, minor, patch}; -}; - -export default (): IInstallationType => { - const out: IInstallationType = { - isUpdate: false, - isFirstInstall: false - }; - - const defaults = getDefaultValues(); - const packageJSON = getPackageJSON(); - - const isFirstInstall = defaults.changelog === undefined || - (defaults.changelog !== undefined && typeof defaults.changelog.lastversion !== 'string'); - - if (isFirstInstall) { - return {...out, isFirstInstall}; - } - - const versionCurrent = splitVersion(packageJSON.version); - const versionOld = isFirstInstall ? null : splitVersion(defaults.changelog.lastversion); - - const isUpdate = !versionOld || - versionCurrent.major > versionOld.major || - versionCurrent.minor > versionOld.minor || - versionCurrent.patch > versionOld.patch; - - return {...out, isUpdate}; -}; diff --git a/src/helpers/fs.ts b/src/helpers/fs.ts deleted file mode 100644 index ee1ee39..0000000 --- a/src/helpers/fs.ts +++ /dev/null @@ -1,47 +0,0 @@ -import * as fs from 'fs'; -import * as path from 'path'; - -import {IPackageJSON} from '../interfaces/ipackage.json'; - -import {CHARSET} from './../consts/files'; -import {IDefaults} from '../interfaces/idefaults'; -import {PATHS} from '../consts/paths'; - -export function ensureDir(dirname: string): void { - if (!fs.existsSync(dirname)) { - fs.mkdirSync(dirname); - } -} - -export function getDefaultValues(): IDefaults { - const defaults: IDefaults = require(path.join(PATHS.VSIX_DIR, 'defaults.json')); - - if (defaults === undefined || defaults === null) { - throw new Error('Cannot find defaults params'); - } - - return defaults; -} - -export function getAbsolutePath(input: string): string { - return path.join(PATHS.VSIX_DIR, input); -} - -export function getAccentsProperties() { - return getDefaultValues().accentsProperties; -} - -/** - * Gets package JSON - */ -export function getPackageJSON(): IPackageJSON { - return require(path.join(PATHS.VSIX_DIR, './package.json')); -} - -/** - * Writes a file inside the vsix directory - */ -export function writeFile(filename: string, filecontent: string): void { - const filePath = path.join(PATHS.VSIX_DIR, filename); - fs.writeFileSync(filePath, filecontent, {encoding: CHARSET}); -} diff --git a/src/helpers/messages.ts b/src/helpers/messages.ts index 969954a..09b1fdf 100644 --- a/src/helpers/messages.ts +++ b/src/helpers/messages.ts @@ -2,7 +2,7 @@ import { window as Window } from 'vscode'; -const MESSAGES = { +export const MESSAGES = { CHANGELOG: { message: 'Material Theme was updated. Check the release notes for more details.', options: {ok: 'Show me', cancel: 'Maybe later'} @@ -12,14 +12,7 @@ const MESSAGES = { } }; -export const changelogMessage = async () => - await Window.showInformationMessage( - MESSAGES.CHANGELOG.message, - MESSAGES.CHANGELOG.options.ok, - MESSAGES.CHANGELOG.options.cancel - ) === MESSAGES.CHANGELOG.options.ok; - -export const installationMessage = async () => - await Window.showInformationMessage( +export const installationMessage = async (): Promise => + Window.showInformationMessage( MESSAGES.INSTALLATION.message ); diff --git a/src/helpers/settings.ts b/src/helpers/settings.ts deleted file mode 100644 index 626cdbd..0000000 --- a/src/helpers/settings.ts +++ /dev/null @@ -1,55 +0,0 @@ -import * as vscode from 'vscode'; - -import {IDefaults} from './../interfaces/idefaults'; -import {IThemeCustomSettings} from './../interfaces/itheme-custom-properties'; -import {getPackageJSON} from './fs'; - -/** - * Gets saved accent - */ -export function getAccent(): string | undefined { - return getCustomSettings().accent; -} - -/** - * Gets custom settings - */ -export function getCustomSettings(): IThemeCustomSettings { - return vscode.workspace.getConfiguration().get('materialTheme', {}); -} - -/** - * Get showReloadNotification - */ -export function isReloadNotificationEnable(): boolean { - return vscode.workspace.getConfiguration().get('materialTheme.showReloadNotification'); -} - -/** - * Checks if a given string could be an accent - */ -export function isAccent(accentName: string, defaults: IDefaults): boolean { - return Boolean(Object.keys(defaults.accents).find(name => name === accentName)); -} - -/** - * Determines if the passing theme id is a material theme - */ -export function isMaterialTheme(themeName: string): boolean { - const packageJSON = getPackageJSON(); - return Boolean(packageJSON.contributes.themes.find(contrib => contrib.label === themeName)); -} - -/** - * Sets a custom property in custom settings - */ -export function setCustomSetting(settingName: string, value: any): Thenable { - return vscode.workspace.getConfiguration().update(`materialTheme.${settingName}`, value, true).then(() => settingName); -} - -/** - * Updates accent name - */ -export function updateAccent(accentName: string): Thenable { - return setCustomSetting('accent', accentName); -} diff --git a/src/helpers/vscode.ts b/src/helpers/vscode.ts deleted file mode 100644 index 86565b1..0000000 --- a/src/helpers/vscode.ts +++ /dev/null @@ -1,15 +0,0 @@ -import * as vscode from 'vscode'; - -/** - * Gets your current theme ID - */ -export function getCurrentThemeID(): string { - return vscode.workspace.getConfiguration().get('workbench.colorTheme'); -} - -/** - * Reloads current vscode window. - */ -export function reloadWindow(): void { - vscode.commands.executeCommand('workbench.action.reloadWindow'); -} diff --git a/src/helpers/write-changelog.ts b/src/helpers/write-changelog.ts deleted file mode 100644 index c53c347..0000000 --- a/src/helpers/write-changelog.ts +++ /dev/null @@ -1,16 +0,0 @@ -import * as path from 'path'; -import {getDefaultValues, getPackageJSON, writeFile} from './fs'; - -import {IDefaults} from '../interfaces/idefaults'; - -const writeDefaults = (defaults: IDefaults) => - writeFile(path.join('./defaults.json'), JSON.stringify(defaults, null, 2)); - -export default (): void => { - const defaults = getDefaultValues(); - const packageJSON = getPackageJSON(); - - const newChangelog = {...defaults.changelog, lastversion: packageJSON.version}; - const newDefaults = {...defaults, changelog: newChangelog}; - writeDefaults(newDefaults); -}; diff --git a/src/interfaces/iaccent-custom-property.ts b/src/interfaces/iaccent-custom-property.ts deleted file mode 100644 index 3c2ca51..0000000 --- a/src/interfaces/iaccent-custom-property.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface IAccentCustomProperty { - alpha: number; - value: any; -} diff --git a/src/interfaces/idefaults.ts b/src/interfaces/idefaults.ts deleted file mode 100644 index 45ab15f..0000000 --- a/src/interfaces/idefaults.ts +++ /dev/null @@ -1,35 +0,0 @@ -import {IGenericObject} from './igeneric-object'; -import {IAccentCustomProperty} from './iaccent-custom-property'; - -export interface IDefaults { - accents: IAccents; - accentsProperties: IGenericObject ; - changelog: IChangelog; - themeVariants: IDefaultsThemeVariant; - themeVariantsColours: IDefaultsThemeVariant; - themeVariantsUITheme: IDefaultsThemeVariant; - [Symbol.iterator](): IterableIterator; -} - -export interface IAccents { - teal: string; - [index: string]: string; -} - -export interface IChangelog { - lastversion: string; - [Symbol.iterator](): IterableIterator; -} - -export interface IDefaultsThemeVariant { - [index: string]: string; - Darker: string; - DarkerHighContrast: string; - Default: string; - DefaultHighContrast: string; - Light: string; - LightHighContrast: string; - PalenightHighContrast: string; - Ocean: string; - OceanHighContrast: string; -} diff --git a/src/interfaces/igeneric-object.ts b/src/interfaces/igeneric-object.ts deleted file mode 100644 index d0515f4..0000000 --- a/src/interfaces/igeneric-object.ts +++ /dev/null @@ -1,3 +0,0 @@ -export interface IGenericObject { - [index: string]: TValue; -} diff --git a/src/interfaces/iinstallation-type.ts b/src/interfaces/iinstallation-type.ts deleted file mode 100644 index b3d6325..0000000 --- a/src/interfaces/iinstallation-type.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface IInstallationType { - isUpdate: boolean; - isFirstInstall: boolean; -} diff --git a/src/interfaces/ipackage.json.ts b/src/interfaces/ipackage.json.ts deleted file mode 100644 index 6e1b871..0000000 --- a/src/interfaces/ipackage.json.ts +++ /dev/null @@ -1,52 +0,0 @@ -import {IGenericObject} from '../interfaces/igeneric-object'; - -export interface IPackageJSONBadge { - description: string; - href: string; - url: string; -} - -export interface IPackageJSONContributes { - commands: IPackageJSONCommand[]; - configuration: IPackageJSONConfiguration; - themes: IPackageJSONTheme[]; -} - -export interface IPackageJSONConfiguration { - properties: {}; -} - -export interface IPackageJSONCommand { - category: string; - command: string; - title: string; -} - -export interface IPackageJSONTheme { - label: string; - path: string; - uiTheme: string; -} - -export interface IPackageJSON { - activationEvents: string[]; - badges: IPackageJSONBadge[]; - contributes: IPackageJSONContributes; - bugs: IGenericObject; - categories: string[]; - description: string; - displayName: string; - engines: IGenericObject; - galleryBanner: IGenericObject; - homepage: string; - icon: string; - license: string; - main: string; - name: string; - preview: boolean; - publisher: string; - repository: IGenericObject; - scripts: IGenericObject; - version: string; - devDependencies: IGenericObject; -} diff --git a/src/interfaces/ipaths.ts b/src/interfaces/ipaths.ts deleted file mode 100644 index f837450..0000000 --- a/src/interfaces/ipaths.ts +++ /dev/null @@ -1,23 +0,0 @@ -export interface IPaths { - /** - * Src dir - */ - SRC: string; - /** - * Themes dir - */ - THEMES: string; - /** - * Extension directory - */ - VSIX_DIR: string; - VSIX_SRC_DIR: string; - /** - * Internal Extensions directory - */ - EXT_DIR: string; - /** - * UI directory - */ - UI: string; -} diff --git a/src/interfaces/itheme-custom-properties.ts b/src/interfaces/itheme-custom-properties.ts deleted file mode 100644 index 0ab1437..0000000 --- a/src/interfaces/itheme-custom-properties.ts +++ /dev/null @@ -1,3 +0,0 @@ -export interface IThemeCustomSettings { - accent?: string; -} diff --git a/src/material.theme.config.ts b/src/material.theme.config.ts index 966a435..3fcd034 100644 --- a/src/material.theme.config.ts +++ b/src/material.theme.config.ts @@ -4,33 +4,25 @@ import { } from 'vscode'; import * as ThemeCommands from './commands'; -import {updateAccent} from './helpers/settings'; -import {changelogMessage, installationMessage} from './helpers/messages'; -import checkInstallation from './helpers/check-installation'; -import writeChangelog from './helpers/write-changelog'; +import {installationMessage} from './helpers/messages'; import {ReleaseNotesWebview} from './webviews/ReleaseNotes'; +import {changelogManager} from './core/changelog-manager'; +import {extensionManager} from './core/extension-manager'; export async function activate(context: ExtensionContext): Promise { - const installationType = checkInstallation(); const releaseNotesView = new ReleaseNotesWebview(context); + const installationType = extensionManager.getInstallationType(); - writeChangelog(); - - if (installationType.isFirstInstall) { + // TODO: BEFORE RELEASE add new message for new install because with the refactor also updates will be considered as new install, for the first time + if (installationType.firstInstall) { await installationMessage(); } - const shouldShowChangelog = (installationType.isFirstInstall || installationType.isUpdate) && await changelogMessage(); - if (shouldShowChangelog) { - releaseNotesView.show(); + if ((installationType.firstInstall || installationType.update) && await changelogManager.askShowChangelog()) { + await releaseNotesView.show(); } // Registering commands - Commands.registerCommand('materialTheme.setAccent', async () => { - const accentPicked = await ThemeCommands.accentsQuickPick(); - await ThemeCommands.accentsSetter(accentPicked); - await updateAccent(accentPicked); - }); - + Commands.registerCommand('materialTheme.setAccent', ThemeCommands.setAccent); Commands.registerCommand('materialTheme.showReleaseNotes', async () => releaseNotesView.show()); } diff --git a/src/webviews/Settings.ts b/src/webviews/Settings.ts index 74ad510..2a14b9f 100644 --- a/src/webviews/Settings.ts +++ b/src/webviews/Settings.ts @@ -1,44 +1,45 @@ -import {WebviewController} from './Webview'; -import { - workspace as Workspace -} from 'vscode'; -import {ISettingsBootstrap} from './interfaces'; -import {getCustomSettings} from '../helpers/settings'; -import {getDefaultValues} from '../helpers/fs'; +// WIP +// Import {WebviewController} from './Webview'; +// import { +// workspace as Workspace +// } from 'vscode'; +// import {ISettingsBootstrap} from './interfaces'; +// import {getCustomSettings} from '../helpers/settings'; +// import {getDefaultValues} from '../helpers/fs'; -export class SettingsWebview extends WebviewController { - get filename(): string { - return 'settings.html'; - } +// export class SettingsWebview extends WebviewController { +// get filename(): string { +// return 'settings.html'; +// } - get id(): string { - return 'materialTheme.settings'; - } +// get id(): string { +// return 'materialTheme.settings'; +// } - get title(): string { - return 'Material Theme Settings'; - } +// get title(): string { +// return 'Material Theme Settings'; +// } - /** - * This will be called by the WebviewController when init the view - * passing as `window.bootstrap` to the view. - */ - getBootstrap(): ISettingsBootstrap { - return { - config: getCustomSettings(), - defaults: getDefaultValues(), - scope: 'user', - scopes: this.getAvailableScopes() - }; - } +// /** +// * This will be called by the WebviewController when init the view +// * passing as `window.bootstrap` to the view. +// */ +// getBootstrap(): ISettingsBootstrap { +// return { +// config: getCustomSettings(), +// defaults: getDefaultValues(), +// scope: 'user', +// scopes: this.getAvailableScopes() +// }; +// } - private getAvailableScopes(): Array<['user' | 'workspace', string]> { - const scopes: Array<['user' | 'workspace', string]> = [['user', 'User']]; - return scopes - .concat( - Workspace.workspaceFolders?.length ? - ['workspace', 'Workspace'] : - [] - ); - } -} +// private getAvailableScopes(): Array<['user' | 'workspace', string]> { +// const scopes: Array<['user' | 'workspace', string]> = [['user', 'User']]; +// return scopes +// .concat( +// Workspace.workspaceFolders?.length ? +// ['workspace', 'Workspace'] : +// [] +// ); +// } +// } diff --git a/src/webviews/Webview.ts b/src/webviews/Webview.ts index 4bf1812..0115540 100644 --- a/src/webviews/Webview.ts +++ b/src/webviews/Webview.ts @@ -12,8 +12,7 @@ import { Uri } from 'vscode'; -import {getCustomSettings} from '../helpers/settings'; -import {Invalidates, Message, ISettingsChangedMessage} from './interfaces'; +import {Invalidates, Message} from './interfaces'; export abstract class WebviewController extends Disposable { private panel: WebviewPanel | undefined; @@ -38,7 +37,7 @@ export abstract class WebviewController extends Disposable { const html = await this.getHtml(); const rootPath = Uri - .file(this.context.asAbsolutePath('./out')) + .file(this.context.asAbsolutePath('./build')) .with({scheme: 'vscode-resource'}).toString(); // Replace placeholders in html content for assets and adding configurations as `window.bootstrap` @@ -93,32 +92,32 @@ export abstract class WebviewController extends Disposable { private async getHtml(): Promise { const doc = await Workspace - .openTextDocument(this.context.asAbsolutePath(path.join('out/ui', this.filename))); + .openTextDocument(this.context.asAbsolutePath(path.join('build/ui', this.filename))); return doc.getText(); } - private async postMessage(message: Message, invalidates: Invalidates = 'all'): Promise { - if (this.panel === undefined) { - return false; - } + // Private async postMessage(message: Message, invalidates: Invalidates = 'all'): Promise { + // if (this.panel === undefined) { + // return false; + // } - const result = await this.panel.webview.postMessage(message); + // const result = await this.panel.webview.postMessage(message); - // If post was ok, update invalidateOnVisible if different than default - if (!result && this.invalidateOnVisible !== 'all') { - this.invalidateOnVisible = invalidates; - } + // // If post was ok, update invalidateOnVisible if different than default + // if (!result && this.invalidateOnVisible !== 'all') { + // this.invalidateOnVisible = invalidates; + // } - return result; - } + // return result; + // } - private async postUpdatedConfiguration(): Promise { - // Post full raw configuration - return this.postMessage({ - type: 'settingsChanged', - config: getCustomSettings() - } as ISettingsChangedMessage, 'config'); - } + // Private async postUpdatedConfiguration(): Promise { + // // Post full raw configuration + // return this.postMessage({ + // type: 'settingsChanged', + // config: getCustomSettings() + // } as ISettingsChangedMessage, 'config'); + // } private onPanelDisposed(): void { if (this.disposablePanel) { @@ -142,7 +141,8 @@ export abstract class WebviewController extends Disposable { switch (invalidContext) { case 'config': // Post the new configuration to the view - return this.postUpdatedConfiguration(); + // return this.postUpdatedConfiguration(); + return; default: return this.show(); } diff --git a/src/webviews/interfaces.ts b/src/webviews/interfaces.ts index 66a8c54..cef9792 100644 --- a/src/webviews/interfaces.ts +++ b/src/webviews/interfaces.ts @@ -1,6 +1,3 @@ -import {IThemeCustomSettings} from '../interfaces/itheme-custom-properties'; -import {IDefaults} from '../interfaces/idefaults'; - export interface IChangeType { children: Array<{ text: string; @@ -22,7 +19,7 @@ export interface IPostNormalized { } export interface ISettingsChangedMessage { type: 'settingsChanged'; - config: IThemeCustomSettings; + config: {}; } export interface ISaveSettingsMessage { @@ -39,13 +36,13 @@ export type Message = ISaveSettingsMessage | ISettingsChangedMessage; export type Invalidates = 'all' | 'config' | undefined; export interface IBootstrap { - config: IThemeCustomSettings; + config: {}; } export interface ISettingsBootstrap extends IBootstrap { scope: 'user' | 'workspace'; scopes: Array<['user' | 'workspace', string]>; - defaults: IDefaults; + defaults: {}; } declare global { diff --git a/src/webviews/ui/release-notes/index.ts b/src/webviews/ui/release-notes/index.ts index 22afe64..ffe38f8 100644 --- a/src/webviews/ui/release-notes/index.ts +++ b/src/webviews/ui/release-notes/index.ts @@ -1,4 +1,4 @@ -import * as sanityClient from '@sanity/client'; +import sanityClient from '@sanity/client'; import {IPost, IPostNormalized} from '../../interfaces'; diff --git a/src/webviews/ui/settings/index.ts b/src/webviews/ui/settings/index.ts index 489b64d..5e3f31f 100644 --- a/src/webviews/ui/settings/index.ts +++ b/src/webviews/ui/settings/index.ts @@ -1,11 +1,11 @@ import {ISettingsBootstrap} from '../../interfaces'; -import accentsSelector from './lib/accents-selector'; +// Import accentsSelector from './lib/accents-selector'; const run = (): void => { bind(); const {config, defaults} = window.bootstrap as ISettingsBootstrap; - accentsSelector('[data-setting="accentSelector"]', defaults.accents, config.accent); + // AccentsSelector('[data-setting="accentSelector"]', defaults.accents, config.accent); console.log(defaults); console.log(config); diff --git a/src/webviews/ui/settings/lib/accents-selector.ts b/src/webviews/ui/settings/lib/accents-selector.ts index 2d103ad..ae7bd95 100644 --- a/src/webviews/ui/settings/lib/accents-selector.ts +++ b/src/webviews/ui/settings/lib/accents-selector.ts @@ -1,4 +1,4 @@ -import {IAccents} from '../../../../interfaces/idefaults'; +// Import {IAccents} from '../../../../interfaces/idefaults'; const templateSingleAccent = (accentName: string, accentColor: string): string => { const dashAccentName = accentName.toLowerCase().replace(/ /gi, '-'); @@ -9,7 +9,7 @@ const templateSingleAccent = (accentName: string, accentColor: string): string = `; }; -export default (containerSelector: string, accentsObject: IAccents, currentAccent: string): void => { +export default (containerSelector: string, accentsObject: Record, currentAccent: string): void => { const container = document.querySelector(containerSelector); for (const accentKey of Object.keys(accentsObject)) { diff --git a/tsconfig.json b/tsconfig.json index b9c07ff..12f5b32 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -19,8 +19,7 @@ "./types", "./src/**/*", "./test/**/*", - "./scripts/**/*", - "./env.ts" + "./scripts/**/*" ], "exclude": [ "node_modules",