From 1e1c0cedb02458ef99643db2c210880093129926 Mon Sep 17 00:00:00 2001 From: Elio Struyf Date: Fri, 14 Jun 2024 13:40:02 +0200 Subject: [PATCH] #812 - Support for case 2 --- src/commands/Article.ts | 6 ++- src/commands/Folders.ts | 57 +++++++++++++++++++++++-- src/commands/Preview.ts | 47 +++++--------------- src/listeners/panel/DataListener.ts | 16 ++++++- src/panelWebView/components/Actions.tsx | 2 +- 5 files changed, 84 insertions(+), 44 deletions(-) diff --git a/src/commands/Article.ts b/src/commands/Article.ts index ffb19993..9992f701 100644 --- a/src/commands/Article.ts +++ b/src/commands/Article.ts @@ -294,7 +294,7 @@ export class Article { /** * Retrieve the slug from the front matter */ - public static getSlug() { + public static getSlug(pathname?: string) { const editor = window.activeTextEditor; if (!editor) { return; @@ -329,6 +329,10 @@ export class Article { return `${prefix}${parsedFile.name}${suffix}`; } + if (parsedFile.name.toLowerCase() === 'index' && pathname) { + return ``; + } + const folderName = basename(dirname(file)); return folderName; } diff --git a/src/commands/Folders.ts b/src/commands/Folders.ts index e2efee57..670b7c24 100644 --- a/src/commands/Folders.ts +++ b/src/commands/Folders.ts @@ -11,7 +11,14 @@ import { } from './../constants'; import { commands, Uri, workspace, window } from 'vscode'; import { basename, dirname, join, relative, sep } from 'path'; -import { ContentFolder, FileInfo, FolderInfo, I18nConfig, StaticFolder } from '../models'; +import { + ContentFolder, + ContentType, + FileInfo, + FolderInfo, + I18nConfig, + StaticFolder +} from '../models'; import uniqBy = require('lodash.uniqby'); import { Template } from './Template'; import { Notifications } from '../helpers/Notifications'; @@ -29,6 +36,7 @@ import { mkdirAsync } from '../utils/mkdirAsync'; import { existsAsync, isWindows } from '../utils'; import * as l10n from '@vscode/l10n'; import { LocalizationKey } from '../localization'; +import { Preview } from './Preview'; export const WORKSPACE_PLACEHOLDER = `[[workspace]]`; @@ -640,7 +648,7 @@ export class Folders { * @param filePath * @returns */ - public static async getFilePrefixBeFilePath(filePath: string) { + public static async getFilePrefixBeFilePath(filePath: string): Promise { const folders = await Folders.get(); if (folders.length > 0) { filePath = parseWinPath(filePath); @@ -672,7 +680,7 @@ export class Folders { public static async getPageFolderByFilePath( filePath: string ): Promise { - const folders = await Folders.get(); + const folders = Folders.getCached(); const parsedPath = parseWinPath(filePath); const pageFolderMatches = folders .filter((folder) => parsedPath && folder.path && parsedPath.includes(folder.path)) @@ -685,6 +693,49 @@ export class Folders { return; } + /** + * Retrieves the folder associated with the specified content type and file path. + * If a single matching folder is found, it is returned. If multiple matching folders are found, + * the user is prompted to select one. If no matching folders are found, the user is prompted to + * select a folder with a preview path. + * + * @param contentType - The content type to match. + * @param filePath - The file path to match. + * @returns A Promise that resolves to the selected ContentFolder, or undefined if no matching folder is found. + */ + public static async getFolderByContentType( + contentType: ContentType, + filePath: string + ): Promise { + if (!contentType) { + return; + } + + const folders = Folders.getCached(); + let selectedFolder: ContentFolder | undefined; + + // Try to find the folder by content type + let crntFolders = folders.filter( + (folder) => + folder.contentTypes?.includes((contentType as ContentType).name) && folder.previewPath + ); + + // Use file path to find the folder + if (crntFolders.length > 0) { + crntFolders = crntFolders.filter((folder) => filePath?.startsWith(folder.path)); + } + + if (crntFolders && crntFolders.length === 1) { + selectedFolder = crntFolders[0]; + } else if (crntFolders && crntFolders.length > 1) { + selectedFolder = await Preview.askUserToPickFolder(crntFolders); + } else { + selectedFolder = await Preview.askUserToPickFolder(folders.filter((f) => f.previewPath)); + } + + return selectedFolder; + } + /** * Retrieves the file stats for a given file. * @param file - The URI of the file. diff --git a/src/commands/Preview.ts b/src/commands/Preview.ts index 0072ad4b..e4785d7d 100644 --- a/src/commands/Preview.ts +++ b/src/commands/Preview.ts @@ -247,42 +247,15 @@ export class Preview { contentType = await ArticleHelper.getContentType(article); } - // Check if there is a pathname defined on content folder level - const folders = await Folders.get(); - if (folders.length > 0) { - for (const folder of folders) { - const folderPath = parseWinPath(folder.path); - if (filePath.startsWith(folderPath)) { - if (!selectedFolder || selectedFolder.path.length < folderPath.length) { - selectedFolder = folder; - } - } - } + // Get the folder of the article by the file path + selectedFolder = await Folders.getPageFolderByFilePath(filePath); - if (!selectedFolder && article?.data && contentType && !contentType.previewPath) { - // Try to find the folder by content type - let crntFolders = folders.filter( - (folder) => - folder.contentTypes?.includes((contentType as ContentType).name) && folder.previewPath - ); + if (!selectedFolder && contentType) { + selectedFolder = await Folders.getFolderByContentType(contentType, filePath); + } - // Use file path to find the folder - if (crntFolders.length > 0) { - crntFolders = crntFolders.filter((folder) => filePath?.startsWith(folder.path)); - } - - if (crntFolders && crntFolders.length === 1) { - selectedFolder = crntFolders[0]; - } else if (crntFolders && crntFolders.length > 1) { - selectedFolder = await Preview.askUserToPickFolder(crntFolders); - } else { - selectedFolder = await Preview.askUserToPickFolder(folders.filter((f) => f.previewPath)); - } - } - - if (selectedFolder && selectedFolder.previewPath) { - pathname = selectedFolder.previewPath; - } + if (selectedFolder && selectedFolder.previewPath) { + pathname = selectedFolder.previewPath; } // Check if there is a pathname defined on content type level @@ -293,7 +266,7 @@ export class Preview { } if (!slug) { - slug = Article.getSlug(); + slug = Article.getSlug(pathname); } const locale = await i18n.getLocale(filePath); @@ -372,7 +345,7 @@ export class Preview { slug = `${slug}/`; } - return slug; + return join(slug); } /** @@ -422,7 +395,7 @@ export class Preview { * @param crntFolders * @returns */ - private static async askUserToPickFolder( + public static async askUserToPickFolder( crntFolders: ContentFolder[] ): Promise { let selectedFolder: ContentFolder | undefined = undefined; diff --git a/src/listeners/panel/DataListener.ts b/src/listeners/panel/DataListener.ts index 2586b022..7391dd71 100644 --- a/src/listeners/panel/DataListener.ts +++ b/src/listeners/panel/DataListener.ts @@ -307,9 +307,21 @@ export class DataListener extends BaseListener { // Check slug if (!slugField && !updatedMetadata[DefaultFields.Slug]) { - const slug = Article.getSlug(); + let pathname = contentType.previewPath || ''; + if (!pathname) { + const selectedFolder = await Folders.getPageFolderByFilePath(filePath); + if (selectedFolder && selectedFolder.previewPath) { + pathname = selectedFolder.previewPath; + } + } - if (slug) { + if (!pathname) { + pathname = Preview.getSettings().pathname || ''; + } + + const slug = Article.getSlug(pathname); + + if (typeof slug !== 'undefined') { updatedMetadata[DefaultFields.Slug] = slug; } } diff --git a/src/panelWebView/components/Actions.tsx b/src/panelWebView/components/Actions.tsx index 841ec968..37bcb04e 100644 --- a/src/panelWebView/components/Actions.tsx +++ b/src/panelWebView/components/Actions.tsx @@ -53,7 +53,7 @@ const Actions: React.FunctionComponent = ({ } if (settings?.preview?.host && !disableActions.includes(`preview`)) { - if ((metadata && metadata.slug) || !metadata) { + if ((metadata && typeof metadata.slug !== "undefined") || !metadata) { allActions.push(); } }