diff --git a/src/commands/Folders.ts b/src/commands/Folders.ts index a4306e7c..c9377430 100644 --- a/src/commands/Folders.ts +++ b/src/commands/Folders.ts @@ -672,6 +672,27 @@ export class Folders { return; } + /** + * Retrieves the file stats for a given file. + * @param file - The URI of the file. + * @param folderPath - The path of the folder containing the file. + * @returns An object containing the file path, file name, folder name, folder path, and file stats. + */ + public static async getFileStats(file: Uri, folderPath: string) { + const fileName = basename(file.fsPath); + const folderName = dirname(file.fsPath).split(sep).pop(); + + const stats = await workspace.fs.stat(file); + + return { + filePath: file.fsPath, + fileName, + folderName, + folderPath, + ...stats + }; + } + private static async getFilesByFolder( folder: ContentFolder, supportedFiles: string[] | undefined, @@ -707,17 +728,8 @@ export class Folders { for (const file of files) { try { - const fileName = basename(file.fsPath); - const folderName = dirname(file.fsPath).split(sep).pop(); - - const stats = await workspace.fs.stat(file); - - fileStats.push({ - filePath: file.fsPath, - fileName, - folderName, - ...stats - }); + const fileInfo = await Folders.getFileStats(file, folderPath); + fileStats.push(fileInfo); } catch (error) { // Skip the file } @@ -731,6 +743,7 @@ export class Folders { return { title: folder.title, + path: folderPath, files: files.length, lastModified: fileStats, locale: folder.locale, diff --git a/src/listeners/dashboard/PagesListener.ts b/src/listeners/dashboard/PagesListener.ts index 685b928d..954742f0 100644 --- a/src/listeners/dashboard/PagesListener.ts +++ b/src/listeners/dashboard/PagesListener.ts @@ -69,7 +69,7 @@ export class PagesListener extends BaseListener { if (ArticleHelper.isSupportedFile(doc)) { Logger.info(`File saved ${doc.uri.fsPath}`); // Optimize the list of recently changed files - DataListener.getFoldersAndFiles(); + DataListener.getFoldersAndFiles(doc.uri); // Trigger the metadata update this.watcherExec(doc.uri); } diff --git a/src/listeners/panel/DataListener.ts b/src/listeners/panel/DataListener.ts index de30851b..4e193394 100644 --- a/src/listeners/panel/DataListener.ts +++ b/src/listeners/panel/DataListener.ts @@ -5,7 +5,7 @@ import { Folders } from '../../commands/Folders'; import { Command } from '../../panelWebView/Command'; import { CommandToCode } from '../../panelWebView/CommandToCode'; import { BaseListener } from './BaseListener'; -import { authentication, commands, window } from 'vscode'; +import { Uri, authentication, commands, window } from 'vscode'; import { ArticleHelper, Extension, @@ -14,7 +14,8 @@ import { ContentType, processArticlePlaceholdersFromData, processTimePlaceholders, - processFmPlaceholders + processFmPlaceholders, + parseWinPath } from '../../helpers'; import { COMMAND_NAME, @@ -29,7 +30,13 @@ import { } from '../../constants'; import { Article, Preview } from '../../commands'; import { FrontMatterParser, ParsedFrontMatter } from '../../parsers'; -import { Field, Mode, PostMessageData, ContentType as IContentType } from '../../models'; +import { + Field, + Mode, + PostMessageData, + ContentType as IContentType, + FolderInfo +} from '../../models'; import { encodeEmoji, fieldWhenClause } from '../../utils'; import { PanelProvider } from '../../panelWebView/PanelProvider'; import { MessageHandlerData } from '@estruyf/vscode'; @@ -37,11 +44,13 @@ import { SponsorAi } from '../../services/SponsorAI'; import { Terminal } from '../../services'; import * as l10n from '@vscode/l10n'; import { LocalizationKey } from '../../localization'; +import { parse } from 'path'; const FILE_LIMIT = 10; export class DataListener extends BaseListener { private static lastMetadataUpdate: any = {}; + private static folderInfo: FolderInfo[] | null = null; /** * Process the messages for the dashboard views @@ -158,7 +167,8 @@ export class DataListener extends BaseListener { /** * Retrieve the information about the registered folders and its files */ - public static async getFoldersAndFiles() { + public static async getFoldersAndFiles(file?: Uri) { + Logger.verbose('DataListener:getFoldersAndFiles:start'); const mode = Settings.get(SETTING_GLOBAL_ACTIVE_MODE); const modes = Settings.get(SETTING_GLOBAL_MODES); @@ -175,9 +185,41 @@ export class DataListener extends BaseListener { } } - const folders = (await Folders.getInfo(FILE_LIMIT)) || null; + if (file && DataListener.folderInfo && DataListener.folderInfo.length > 0) { + Logger.verbose('DataListener:getFoldersAndFiles:updateFile'); + const folderPath = parseWinPath(parse(file.fsPath).dir); + const folderInfo = DataListener.folderInfo.find((f) => parseWinPath(f.path) === folderPath); + if (folderInfo) { + // Check if file exists + let fileInfo = folderInfo.lastModified.find( + (f) => parseWinPath(f.filePath) === parseWinPath(file.fsPath) + ); + + if (fileInfo) { + folderInfo.lastModified = folderInfo.lastModified.filter( + (f) => parseWinPath(f.filePath) !== parseWinPath(file.fsPath) + ); + } + + fileInfo = await Folders.getFileStats(file, folderInfo.path); + if (fileInfo) { + folderInfo.lastModified.unshift(fileInfo); + + // Limit the amount of files + if (folderInfo.lastModified.length > FILE_LIMIT) { + folderInfo.lastModified = folderInfo.lastModified.slice(0, FILE_LIMIT); + } + + Logger.verbose('DataListener:getFoldersAndFiles:end - with file update only'); + this.sendMsg(Command.folderInfo, DataListener.folderInfo); + return; + } + } + } - this.sendMsg(Command.folderInfo, folders); + Logger.verbose('DataListener:getFoldersAndFiles:end'); + DataListener.folderInfo = (await Folders.getInfo(FILE_LIMIT)) || null; + this.sendMsg(Command.folderInfo, DataListener.folderInfo); } /** diff --git a/src/models/PanelSettings.ts b/src/models/PanelSettings.ts index fca2e8a7..a65d79a8 100644 --- a/src/models/PanelSettings.ts +++ b/src/models/PanelSettings.ts @@ -189,6 +189,7 @@ export interface Slug { export interface FolderInfo { title: string; + path: string; files: number; lastModified: FileInfo[]; locale?: string; @@ -199,6 +200,7 @@ export interface FileInfo extends FileStat { filePath: string; fileName: string; folderName: string | undefined; + folderPath: string; } export interface CustomScript {