diff --git a/CHANGELOG.md b/CHANGELOG.md index 071a2b54..59759bf9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ - [#662](https://github.com/estruyf/vscode-front-matter/issues/662): Always show the `all articles` tab with the page counter - [#663](https://github.com/estruyf/vscode-front-matter/issues/663): Make card tags clickable to filter the view - [#669](https://github.com/estruyf/vscode-front-matter/issues/669): Add the video preview to the details panel + caption field +- [#676](https://github.com/estruyf/vscode-front-matter/issues/676): Allow the `frontmatter.json` file to be placed in a sub-directory ### ⚡️ Optimizations diff --git a/src/commands/Dashboard.ts b/src/commands/Dashboard.ts index 7becdc3a..60de2f8c 100644 --- a/src/commands/Dashboard.ts +++ b/src/commands/Dashboard.ts @@ -135,7 +135,7 @@ export class Dashboard { light: Uri.file(join(extensionUri.fsPath, 'assets/icons/frontmatter-short-light.svg')) }; - Dashboard.webview.webview.html = Dashboard.getWebviewContent( + Dashboard.webview.webview.html = await Dashboard.getWebviewContent( Dashboard.webview.webview, extensionUri ); @@ -218,7 +218,7 @@ export class Dashboard { * Retrieve the webview HTML contents * @param webView */ - private static getWebviewContent(webView: Webview, extensionPath: Uri): string { + private static async getWebviewContent(webView: Webview, extensionPath: Uri): Promise { const dashboardFile = 'dashboardWebView.js'; const localPort = `9000`; const localServerUrl = `localhost:${localPort}`; @@ -276,10 +276,9 @@ export class Dashboard { }` ]; + const globalConfigPath = await SettingsHelper.projectConfigPath(); const frontMatterUri = webView - .asWebviewUri( - SettingsHelper.projectConfigPath ? Uri.file(SettingsHelper.projectConfigPath) : Uri.file('') - ) + .asWebviewUri(globalConfigPath ? Uri.file(globalConfigPath) : Uri.file('')) .toString(); const webviewUrl = frontMatterUri.replace(`/${SettingsHelper.globalFile}`, ''); diff --git a/src/commands/Folders.ts b/src/commands/Folders.ts index 221a4910..f8945df3 100644 --- a/src/commands/Folders.ts +++ b/src/commands/Folders.ts @@ -592,7 +592,7 @@ export class Folders { */ private static findFolders(pattern: string): Promise { return new Promise((resolve) => { - glob(pattern, { ignore: '**/node_modules/**' }, (err, files) => { + glob(pattern, { ignore: '**/node_modules/**', dot: true }, (err, files) => { const allFolders = files.map((file) => dirname(file)); const uniqueFolders = [...new Set(allFolders)]; resolve(uniqueFolders); diff --git a/src/commands/Project.ts b/src/commands/Project.ts index 7fe1c953..2281ae63 100644 --- a/src/commands/Project.ts +++ b/src/commands/Project.ts @@ -43,8 +43,8 @@ categories: [] subscriptions.push(commands.registerCommand(COMMAND_NAME.switchProject, Project.switchProject)); } - public static isInitialized() { - const hasProjectFile = Settings.hasProjectFile(); + public static async isInitialized() { + const hasProjectFile = await Settings.hasProjectFile(); // If it has a project file, initialize the media library if (hasProjectFile) { MediaLibrary.getInstance(); diff --git a/src/helpers/ContentType.ts b/src/helpers/ContentType.ts index 9078276e..325d5b56 100644 --- a/src/helpers/ContentType.ts +++ b/src/helpers/ContentType.ts @@ -254,7 +254,7 @@ export class ContentType { await Settings.update(SETTING_TAXONOMY_CONTENT_TYPES, contentTypes, true); - const configPath = Settings.projectConfigPath; + const configPath = await Settings.projectConfigPath(); const notificationAction = await Notifications.info( `Content type ${contentTypeName} has been ${overrideBool ? `updated` : `generated`}.`, configPath && (await existsAsync(configPath)) ? `Open settings` : undefined @@ -291,7 +291,7 @@ export class ContentType { await Settings.update(SETTING_TAXONOMY_CONTENT_TYPES, contentTypes, true); - const configPath = Settings.projectConfigPath; + const configPath = await Settings.projectConfigPath(); const notificationAction = await Notifications.info( `Content type ${contentType.name} has been updated.`, configPath && (await existsAsync(configPath)) ? `Open settings` : undefined diff --git a/src/helpers/DashboardSettings.ts b/src/helpers/DashboardSettings.ts index b8cb3ba3..21dd7688 100644 --- a/src/helpers/DashboardSettings.ts +++ b/src/helpers/DashboardSettings.ts @@ -62,7 +62,7 @@ export class DashboardSettings { public static async getSettings() { const ext = Extension.getInstance(); const wsFolder = Folders.getWorkspaceFolder(); - const isInitialized = Project.isInitialized(); + const isInitialized = await Project.isInitialized(); const gitActions = Settings.get(SETTING_GIT_ENABLED); const pagination = Settings.get(SETTING_DASHBOARD_CONTENT_PAGINATION); diff --git a/src/helpers/PanelSettings.ts b/src/helpers/PanelSettings.ts index 47906fee..19c24584 100644 --- a/src/helpers/PanelSettings.ts +++ b/src/helpers/PanelSettings.ts @@ -77,7 +77,7 @@ export class PanelSettings { scripts: (Settings.get(SETTING_CUSTOM_SCRIPTS) || []).filter( (s) => (s.type === ScriptType.Content || !s.type) && !s.hidden ), - isInitialized: Project.isInitialized(), + isInitialized: await Project.isInitialized(), modifiedDateUpdate: Settings.get(SETTING_AUTO_UPDATE_DATE) || false, writingSettingsEnabled: this.isWritingSettingsEnabled() || false, fmHighlighting: Settings.get(SETTING_CONTENT_FRONTMATTER_HIGHLIGHT), diff --git a/src/helpers/SettingsHelper.ts b/src/helpers/SettingsHelper.ts index 989c3cc5..9cf823c1 100644 --- a/src/helpers/SettingsHelper.ts +++ b/src/helpers/SettingsHelper.ts @@ -55,6 +55,7 @@ import { ModeSwitch } from '../services/ModeSwitch'; export class Settings { public static globalFile = 'frontmatter.json'; public static globalConfigFolder = '.frontmatter/config'; + public static globalConfigPath: string | undefined = undefined; public static globalConfig: any; private static config: vscode.WorkspaceConfiguration; private static isInitialized: boolean = false; @@ -230,14 +231,14 @@ export class Settings { * Check for config changes on global and local settings * @param callback */ - public static onConfigChange() { - const projectConfig = Settings.projectConfigPath; + public static async onConfigChange() { + const projectConfig = await Settings.projectConfigPath(); workspace.onDidChangeConfiguration(() => { Settings.triggerListeners(); }); - if (projectConfig && !existsSync(projectConfig)) { + if (projectConfig && !(await existsAsync(projectConfig))) { // No config file, no need to watch Settings.createFileCreationWatcher(); return; @@ -268,7 +269,7 @@ export class Settings { Settings.fileSaveListener = workspace.onDidSaveTextDocument(async (e) => { const filename = e.uri.fsPath; - if (Settings.checkProjectConfig(filename)) { + if (await Settings.checkProjectConfig(filename)) { Logger.info(`Config change detected - ${filename} saved`); await Settings.reloadConfig(); } @@ -279,7 +280,7 @@ export class Settings { } Settings.fileDeleteListener = workspace.onDidDeleteFiles(async (e) => { - const needCallback = e?.files.find((f) => Settings.checkProjectConfig(f.fsPath)); + const needCallback = e?.files.find(async (f) => await Settings.checkProjectConfig(f.fsPath)); if (needCallback) { await Settings.reloadConfig(false); } @@ -354,7 +355,7 @@ export class Settings { * @param value */ public static async update(name: string, value: T, updateGlobal: boolean = false) { - const fmConfig = Settings.projectConfigPath; + const fmConfig = await Settings.projectConfigPath(); if (updateGlobal) { if (fmConfig && (await existsAsync(fmConfig))) { @@ -385,7 +386,7 @@ export class Settings { } public static async remove(name: string) { - const fmConfig = Settings.projectConfigPath; + const fmConfig = await Settings.projectConfigPath(); if (fmConfig && (await existsAsync(fmConfig))) { const localConfig = await readFileAsync(fmConfig, 'utf8'); @@ -412,10 +413,18 @@ export class Settings { /** * Checks if the project contains the frontmatter.json file */ - public static hasProjectFile() { + public static async hasProjectFile(): Promise { const wsFolder = Folders.getWorkspaceFolder(); - const configPath = join(wsFolder?.fsPath || '', Settings.globalFile); - return existsSync(configPath); + if (!wsFolder) { + return false; + } + + const globalConfigPath = await Settings.projectConfigPath(); + if (!globalConfigPath) { + return false; + } + + return await existsAsync(globalConfigPath); } /** @@ -565,13 +574,21 @@ export class Settings { * Get the project config path * @returns */ - public static get projectConfigPath() { - const wsFolder = Folders.getWorkspaceFolder(); - if (wsFolder) { - const fmConfig = join(wsFolder.fsPath, Settings.globalFile); - return fmConfig; + public static async projectConfigPath() { + if (Settings.globalConfigPath) { + return Settings.globalConfigPath; } - return undefined; + + const configFiles = await workspace.findFiles(`**/${Settings.globalFile}`); + if (configFiles.length === 0) { + Settings.globalConfigPath = undefined; + return Settings.globalConfigPath; + } + + const configPath = configFiles[0].fsPath; + Settings.globalConfigPath = configPath; + + return Settings.globalConfigPath; } /** @@ -579,8 +596,8 @@ export class Settings { * @param filePath * @returns */ - private static checkProjectConfig(filePath: string) { - const fmConfig = Settings.projectConfigPath; + private static async checkProjectConfig(filePath: string) { + const fmConfig = await Settings.projectConfigPath(); filePath = parseWinPath(filePath); if (filePath.includes(Settings.globalConfigFolder)) { @@ -601,7 +618,7 @@ export class Settings { */ private static async readConfig() { try { - const fmConfig = Settings.projectConfigPath; + const fmConfig = await Settings.projectConfigPath(); if (fmConfig && (await existsAsync(fmConfig))) { const localConfig = await readFileAsync(fmConfig, 'utf8'); Settings.globalConfig = jsoncParser.parse(localConfig); @@ -989,8 +1006,9 @@ export class Settings { true ); Settings.fileCreationWatcher.onDidCreate( - (uri) => { - if (parseWinPath(uri.fsPath) === parseWinPath(Settings.projectConfigPath)) { + async (uri) => { + const globalConfigPath = await Settings.projectConfigPath(); + if (globalConfigPath && parseWinPath(uri.fsPath) === parseWinPath(globalConfigPath)) { Settings.onConfigChange(); Settings.rebindWatchers(); // Stop listening to file creation events diff --git a/src/localization/localization.enum.ts b/src/localization/localization.enum.ts index bbdbe615..5f789344 100644 --- a/src/localization/localization.enum.ts +++ b/src/localization/localization.enum.ts @@ -928,9 +928,13 @@ export enum LocalizationKey { */ dashboardWelcomeScreenLinkGithubTitle = 'dashboard.welcomeScreen.link.github.title', /** - * GitHub / Documentation + * GitHub */ dashboardWelcomeScreenLinkGithubLabel = 'dashboard.welcomeScreen.link.github.label', + /** + * Documentation + */ + dashboardWelcomeScreenLinkDocumentationLabel = 'dashboard.welcomeScreen.link.documentation.label', /** * Become a sponsor */