mirror of
https://github.com/estruyf/vscode-front-matter.git
synced 2026-08-07 17:32:58 +02:00
#233 - Partial dashboard update on file change
This commit is contained in:
+104
-64
@@ -1,6 +1,6 @@
|
||||
import { isValidFile } from './../helpers/isValidFile';
|
||||
import { existsSync } from "fs";
|
||||
import { dirname, join } from "path";
|
||||
import { basename, dirname, join } from "path";
|
||||
import { commands, FileSystemWatcher, RelativePattern, Uri, workspace } from "vscode";
|
||||
import { Dashboard } from "../commands/Dashboard";
|
||||
import { Folders } from "../commands/Folders";
|
||||
@@ -8,7 +8,7 @@ import { COMMAND_NAME, DefaultFields, SETTINGS_CONTENT_STATIC_FOLDER, SETTING_DA
|
||||
import { DashboardCommand } from "../dashboardWebView/DashboardCommand";
|
||||
import { DashboardMessage } from "../dashboardWebView/DashboardMessage";
|
||||
import { Page } from "../dashboardWebView/models";
|
||||
import { ArticleHelper, Settings } from "../helpers";
|
||||
import { ArticleHelper, Logger, Settings } from "../helpers";
|
||||
import { ContentType } from "../helpers/ContentType";
|
||||
import { DateHelper } from "../helpers/DateHelper";
|
||||
import { Notifications } from "../helpers/Notifications";
|
||||
@@ -17,6 +17,7 @@ import { BaseListener } from "./BaseListener";
|
||||
|
||||
export class PagesListener extends BaseListener {
|
||||
private static watchers: { [path: string]: FileSystemWatcher } = {};
|
||||
private static lastPages: Page[] = [];
|
||||
|
||||
/**
|
||||
* Start watching the folders in the current workspace for content changes
|
||||
@@ -39,9 +40,10 @@ export class PagesListener extends BaseListener {
|
||||
// Recreate all the watchers
|
||||
for (const folder of folders) {
|
||||
const folderUri = Uri.parse(folder.path);
|
||||
let watcher = workspace.createFileSystemWatcher(new RelativePattern(folderUri, "*"));
|
||||
watcher.onDidCreate(async (uri: Uri) => this.getPagesData);
|
||||
watcher.onDidDelete(async (uri: Uri) => this.getPagesData);
|
||||
let watcher = workspace.createFileSystemWatcher(new RelativePattern(folderUri, "*"), false, false, false);
|
||||
watcher.onDidCreate(async (uri: Uri) => this.watcherExec(uri));
|
||||
watcher.onDidChange(async (uri: Uri) => this.watcherExec(uri));
|
||||
watcher.onDidDelete(async (uri: Uri) => this.watcherExec(uri));
|
||||
this.watchers[folderUri.fsPath] = watcher;
|
||||
}
|
||||
}
|
||||
@@ -69,16 +71,29 @@ export class PagesListener extends BaseListener {
|
||||
}
|
||||
}
|
||||
|
||||
private static async watcherExec(file: Uri) {
|
||||
if (Dashboard.isOpen) {
|
||||
Logger.info(`File watcher execution for: ${file.fsPath}`)
|
||||
|
||||
const pageIdx = this.lastPages.findIndex(p => p.fmFilePath === file.fsPath);
|
||||
if (pageIdx !== -1) {
|
||||
const stats = await workspace.fs.stat(file);
|
||||
const crntPage = this.lastPages[pageIdx];
|
||||
const updatedPage = this.processPageContent(file.fsPath, stats.mtime, basename(file.fsPath), crntPage.fmFolder);
|
||||
if (updatedPage) {
|
||||
this.lastPages[pageIdx] = updatedPage;
|
||||
this.sendMsg(DashboardCommand.pages, this.lastPages);
|
||||
}
|
||||
} else {
|
||||
this.getPagesData();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve all the markdown pages
|
||||
*/
|
||||
private static async getPagesData() {
|
||||
const wsFolder = Folders.getWorkspaceFolder();
|
||||
|
||||
const descriptionField = Settings.get(SETTING_SEO_DESCRIPTION_FIELD) as string || DefaultFields.Description;
|
||||
const dateField = Settings.get(SETTING_DATE_FIELD) as string || DefaultFields.PublishingDate;
|
||||
const staticFolder = Settings.get<string>(SETTINGS_CONTENT_STATIC_FOLDER);
|
||||
|
||||
const folderInfo = await Folders.getInfo();
|
||||
const pages: Page[] = [];
|
||||
|
||||
@@ -87,62 +102,12 @@ export class PagesListener extends BaseListener {
|
||||
for (const file of folder.lastModified) {
|
||||
if (isValidFile(file.fileName)) {
|
||||
try {
|
||||
const article = ArticleHelper.getFrontMatterByPath(file.filePath);
|
||||
const page = this.processPageContent(file.filePath, file.mtime, file.fileName, folder.title);
|
||||
|
||||
if (article?.data.title) {
|
||||
const page: Page = {
|
||||
...article.data,
|
||||
// FrontMatter properties
|
||||
fmFolder: folder.title,
|
||||
fmModified: file.mtime,
|
||||
fmFilePath: file.filePath,
|
||||
fmFileName: file.fileName,
|
||||
fmDraft: ContentType.getDraftStatus(article?.data),
|
||||
fmYear: article?.data[dateField] ? DateHelper.tryParse(article?.data[dateField])?.getFullYear() : null,
|
||||
// Make sure these are always set
|
||||
title: article?.data.title,
|
||||
slug: article?.data.slug,
|
||||
date: article?.data[dateField] || "",
|
||||
draft: article?.data.draft,
|
||||
description: article?.data[descriptionField] || "",
|
||||
};
|
||||
|
||||
const contentType = ArticleHelper.getContentType(article.data);
|
||||
const previewField = contentType.fields.find(field => field.isPreviewImage && field.type === "image")?.name || "preview";
|
||||
|
||||
if (article?.data[previewField] && wsFolder) {
|
||||
let fieldValue = article?.data[previewField];
|
||||
if (fieldValue && Array.isArray(fieldValue)) {
|
||||
if (fieldValue.length > 0) {
|
||||
fieldValue = fieldValue[0];
|
||||
} else {
|
||||
fieldValue = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
// Revalidate as the array could have been empty
|
||||
if (fieldValue) {
|
||||
const staticPath = join(wsFolder.fsPath, staticFolder || "", fieldValue);
|
||||
const contentFolderPath = join(dirname(file.filePath), fieldValue);
|
||||
|
||||
let previewUri = null;
|
||||
if (existsSync(staticPath)) {
|
||||
previewUri = Uri.file(staticPath);
|
||||
} else if (existsSync(contentFolderPath)) {
|
||||
previewUri = Uri.file(contentFolderPath);
|
||||
}
|
||||
|
||||
if (previewUri) {
|
||||
const preview = Dashboard.getWebview()?.asWebviewUri(previewUri);
|
||||
page[previewField] = preview?.toString() || "";
|
||||
} else {
|
||||
page[previewField] = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (page) {
|
||||
pages.push(page);
|
||||
}
|
||||
|
||||
} catch (error: any) {
|
||||
Notifications.error(`File error: ${file.filePath} - ${error?.message || error}`);
|
||||
}
|
||||
@@ -151,10 +116,85 @@ export class PagesListener extends BaseListener {
|
||||
}
|
||||
}
|
||||
|
||||
this.lastPages = pages;
|
||||
this.sendMsg(DashboardCommand.pages, pages);
|
||||
}
|
||||
|
||||
public static refresh() {
|
||||
this.getPagesData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the page content
|
||||
* @param filePath
|
||||
* @param fileMtime
|
||||
* @param fileName
|
||||
* @param folderTitle
|
||||
* @returns
|
||||
*/
|
||||
private static processPageContent(filePath: string, fileMtime: number, fileName: string, folderTitle: string): Page | undefined {
|
||||
const article = ArticleHelper.getFrontMatterByPath(filePath);
|
||||
|
||||
if (article?.data.title) {
|
||||
const wsFolder = Folders.getWorkspaceFolder();
|
||||
const descriptionField = Settings.get(SETTING_SEO_DESCRIPTION_FIELD) as string || DefaultFields.Description;
|
||||
const dateField = Settings.get(SETTING_DATE_FIELD) as string || DefaultFields.PublishingDate;
|
||||
const staticFolder = Settings.get<string>(SETTINGS_CONTENT_STATIC_FOLDER);
|
||||
|
||||
const page: Page = {
|
||||
...article.data,
|
||||
// FrontMatter properties
|
||||
fmFolder: folderTitle,
|
||||
fmModified: fileMtime,
|
||||
fmFilePath: filePath,
|
||||
fmFileName: fileName,
|
||||
fmDraft: ContentType.getDraftStatus(article?.data),
|
||||
fmYear: article?.data[dateField] ? DateHelper.tryParse(article?.data[dateField])?.getFullYear() : null,
|
||||
// Make sure these are always set
|
||||
title: article?.data.title,
|
||||
slug: article?.data.slug,
|
||||
date: article?.data[dateField] || "",
|
||||
draft: article?.data.draft,
|
||||
description: article?.data[descriptionField] || "",
|
||||
};
|
||||
|
||||
const contentType = ArticleHelper.getContentType(article.data);
|
||||
const previewField = contentType.fields.find(field => field.isPreviewImage && field.type === "image")?.name || "preview";
|
||||
|
||||
if (article?.data[previewField] && wsFolder) {
|
||||
let fieldValue = article?.data[previewField];
|
||||
if (fieldValue && Array.isArray(fieldValue)) {
|
||||
if (fieldValue.length > 0) {
|
||||
fieldValue = fieldValue[0];
|
||||
} else {
|
||||
fieldValue = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
// Revalidate as the array could have been empty
|
||||
if (fieldValue) {
|
||||
const staticPath = join(wsFolder.fsPath, staticFolder || "", fieldValue);
|
||||
const contentFolderPath = join(dirname(filePath), fieldValue);
|
||||
|
||||
let previewUri = null;
|
||||
if (existsSync(staticPath)) {
|
||||
previewUri = Uri.file(staticPath);
|
||||
} else if (existsSync(contentFolderPath)) {
|
||||
previewUri = Uri.file(contentFolderPath);
|
||||
}
|
||||
|
||||
if (previewUri) {
|
||||
const preview = Dashboard.getWebview()?.asWebviewUri(previewUri);
|
||||
page[previewField] = preview?.toString() || "";
|
||||
} else {
|
||||
page[previewField] = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user